diff options
356 files changed, 6331 insertions, 1703 deletions
diff --git a/.buckconfig b/.buckconfig index 8d2572bfda..798649407c 100644 --- a/.buckconfig +++ b/.buckconfig @@ -12,6 +12,8 @@ [java] src_roots = src, resources, tst + source_level = 8 + target_level = 8 [project] ignore = .git diff --git a/.buckversion b/.buckversion index f5fe016979..7eb591fec5 100644 --- a/.buckversion +++ b/.buckversion @@ -1 +1 @@ -e64a2e2ada022f81e42be750b774024469551398 +e27df656657f93f8d57a7aaac69a5ae0e298a292 diff --git a/.gitignore b/.gitignore index 95ad1744b5..e78f8fd9b1 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ /buck-cache /buck-out /target +infer-out diff --git a/.mvn/jvm.config b/.mvn/jvm.config new file mode 100644 index 0000000000..9b109f3737 --- /dev/null +++ b/.mvn/jvm.config @@ -0,0 +1 @@ +-Xmx1024m
\ No newline at end of file diff --git a/.mvn/maven.config b/.mvn/maven.config new file mode 100644 index 0000000000..ebbe28853d --- /dev/null +++ b/.mvn/maven.config @@ -0,0 +1 @@ +-T 1C @@ -72,7 +72,7 @@ Warnings/Caveats - Only the timestamp of the index is used by jgit if the index is dirty. -- JGit requires at least a Java 7 JDK. +- JGit requires at least a Java 8 JDK. - CRLF conversion is performed depending on the core.autocrlf setting, however Git for Windows by default stores that setting during @@ -9,11 +9,11 @@ maven_jar( maven_jar( name = 'javaewah', - bin_sha1 = 'eceaf316a8faf0e794296ebe158ae110c7d72a5a', - src_sha1 = 'a50d78eb630e05439461f3130b94b3bcd1ea6f03', + bin_sha1 = '94ad16d728b374d65bd897625f3fbb3da223a2b6', + src_sha1 = 'ca2745e91c6a51f8e6809d1579bda36ad83f1f58', group = 'com.googlecode.javaewah', artifact = 'JavaEWAH', - version = '0.7.9', + version = '1.1.6', ) maven_jar( diff --git a/lib/jetty/BUCK b/lib/jetty/BUCK index 6e7dec3062..fbb37c1e6a 100644 --- a/lib/jetty/BUCK +++ b/lib/jetty/BUCK @@ -1,10 +1,10 @@ -VERSION = '9.2.13.v20150730' +VERSION = '9.3.17.v20170317' GROUP = 'org.eclipse.jetty' maven_jar( name = 'servlet', - bin_sha1 = '5ad6e38015a97ae9a60b6c2ad744ccfa9cf93a50', - src_sha1 = '78fbec19321150552d91f9e079c2f2ca33222b01', + bin_sha1 = 'ed6986b0d0ca7b9b0f9015c9efb80442e3043a8e', + src_sha1 = 'ee6b4784a00a92e5c1b6111033b7ae41ac6052a3', group = GROUP, artifact = 'jetty-servlet', version = VERSION, @@ -12,8 +12,8 @@ maven_jar( maven_jar( name = 'security', - bin_sha1 = 'cc7c7f27ec4cc279253be1675d9e47e58b995943', - src_sha1 = '75632ebdf8bd651faafb97106c92496db59e165d', + bin_sha1 = 'ca52535569445682d42aaa97c7039442719a0507', + src_sha1 = '2ff9f4fb18b320fd5a0272a427bacc4d5fe7bc86', group = GROUP, artifact = 'jetty-security', version = VERSION, @@ -21,8 +21,8 @@ maven_jar( maven_jar( name = 'server', - bin_sha1 = '5be7d1da0a7abffd142de3091d160717c120b6ab', - src_sha1 = '203e123f83efe2a5b8a9c74854c7897fe3563302', + bin_sha1 = '194e9a02e6ba249ef4a3f4bd56b4993087992299', + src_sha1 = '0c9bd572f530c411592aefb71781ecca0b3719a9', group = GROUP, artifact = 'jetty-server', version = VERSION, @@ -30,8 +30,8 @@ maven_jar( maven_jar( name = 'http', - bin_sha1 = '23a745d9177ef67ef53cc46b9b70c5870082efc2', - src_sha1 = '5f87f7ff2057cd4b0995bc4fffe17b2aff64c130', + bin_sha1 = '6c02d728e15d4868486254039c867a1ac3e4a52e', + src_sha1 = '3c0a2a82792f268631b4fefd77be9f126ec974b1', group = GROUP, artifact = 'jetty-http', version = VERSION, @@ -39,8 +39,8 @@ maven_jar( maven_jar( name = 'io', - bin_sha1 = '7a351e6a1b63dfd56b6632623f7ca2793ffb67ad', - src_sha1 = 'bbd61a84b748fc295456e1c5c3070aaf40a68f62', + bin_sha1 = '756a8cd2a1cbfb84a94973b6332dd3eccd47c0cd', + src_sha1 = 'a9afa99cccb19b441364fa805d027f457cbbb136', group = GROUP, artifact = 'jetty-io', version = VERSION, @@ -48,8 +48,8 @@ maven_jar( maven_jar( name = 'util', - bin_sha1 = 'c101476360a7cdd0670462de04053507d5e70c97', - src_sha1 = '15ceecce141971b4e0facb861b3d10120ad6ce03', + bin_sha1 = 'b8512ab02819de01f0f5a5c6026163041f579beb', + src_sha1 = '96f8e3dcdc3660a5c91f19c46695daa70ac95625', group = GROUP, artifact = 'jetty-util', version = VERSION, diff --git a/org.eclipse.jgit.ant.test/.classpath b/org.eclipse.jgit.ant.test/.classpath index 098194ca4b..eca7bdba8f 100644 --- a/org.eclipse.jgit.ant.test/.classpath +++ b/org.eclipse.jgit.ant.test/.classpath @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <classpath> - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> <classpathentry kind="src" path="src"/> <classpathentry kind="output" path="bin"/> 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 87210fb160..10c29d5576 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 @@ -7,9 +7,9 @@ org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nul org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.7 +org.eclipse.jdt.core.compiler.compliance=1.8 org.eclipse.jdt.core.compiler.debug.lineNumber=generate org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.debug.sourceFile=generate @@ -112,7 +112,7 @@ org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=error -org.eclipse.jdt.core.compiler.source=1.7 +org.eclipse.jdt.core.compiler.source=1.8 org.eclipse.jdt.core.formatter.align_type_members_on_columns=false org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 diff --git a/org.eclipse.jgit.ant.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.ant.test/META-INF/MANIFEST.MF index 5eff9d9408..3bf69c36a9 100644 --- a/org.eclipse.jgit.ant.test/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.ant.test/META-INF/MANIFEST.MF @@ -3,14 +3,14 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Bundle-SymbolicName: org.eclipse.jgit.ant.test -Bundle-Version: 4.5.3.qualifier +Bundle-Version: 4.6.2.qualifier Bundle-ActivationPolicy: lazy -Bundle-RequiredExecutionEnvironment: JavaSE-1.7 +Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Import-Package: org.apache.tools.ant, - org.eclipse.jgit.ant.tasks;version="[4.5.3,4.6.0)", - org.eclipse.jgit.internal.storage.file;version="[4.5.3,4.6.0)", - org.eclipse.jgit.junit;version="[4.5.3,4.6.0)", - org.eclipse.jgit.lib;version="[4.5.3,4.6.0)", - org.eclipse.jgit.util;version="[4.5.3,4.6.0)", + 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.junit;version="[4.0.0,5.0.0)" diff --git a/org.eclipse.jgit.ant.test/build.properties b/org.eclipse.jgit.ant.test/build.properties index e3effea194..4a2d892829 100644 --- a/org.eclipse.jgit.ant.test/build.properties +++ b/org.eclipse.jgit.ant.test/build.properties @@ -3,5 +3,5 @@ output.. = bin/ bin.includes = plugin.properties,\ META-INF/,\ . -jre.compilation.profile = JavaSE-1.7 +jre.compilation.profile = JavaSE-1.8 additional.bundles = org.eclipse.jgit diff --git a/org.eclipse.jgit.ant.test/pom.xml b/org.eclipse.jgit.ant.test/pom.xml index ea581329a3..9592841b2b 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.5.3-SNAPSHOT</version> + <version>4.6.2-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.ant.test</artifactId> diff --git a/org.eclipse.jgit.ant/.classpath b/org.eclipse.jgit.ant/.classpath index a14ade4efd..110168ffa1 100644 --- a/org.eclipse.jgit.ant/.classpath +++ b/org.eclipse.jgit.ant/.classpath @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <classpath> - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> <classpathentry kind="src" path="src"/> <classpathentry kind="src" path="resources"/> 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 cd620c394e..80cfbbbd3b 100644 --- a/org.eclipse.jgit.ant/.settings/org.eclipse.jdt.core.prefs +++ b/org.eclipse.jgit.ant/.settings/org.eclipse.jdt.core.prefs @@ -7,9 +7,9 @@ org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nul org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.7 +org.eclipse.jdt.core.compiler.compliance=1.8 org.eclipse.jdt.core.compiler.debug.lineNumber=generate org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.debug.sourceFile=generate @@ -112,7 +112,7 @@ org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=error -org.eclipse.jdt.core.compiler.source=1.7 +org.eclipse.jdt.core.compiler.source=1.8 org.eclipse.jdt.core.formatter.align_type_members_on_columns=false org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 diff --git a/org.eclipse.jgit.ant/META-INF/MANIFEST.MF b/org.eclipse.jgit.ant/META-INF/MANIFEST.MF index dfa93113f4..6b008e16e3 100644 --- a/org.eclipse.jgit.ant/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.ant/META-INF/MANIFEST.MF @@ -2,11 +2,11 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %Bundle-Name Bundle-SymbolicName: org.eclipse.jgit.ant -Bundle-Version: 4.5.3.qualifier -Bundle-RequiredExecutionEnvironment: JavaSE-1.7 +Bundle-Version: 4.6.2.qualifier +Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Import-Package: org.apache.tools.ant, - org.eclipse.jgit.storage.file;version="[4.5.3,4.6.0)" + org.eclipse.jgit.storage.file;version="[4.6.2,4.7.0)" Bundle-Localization: plugin Bundle-Vendor: %Provider-Name -Export-Package: org.eclipse.jgit.ant.tasks;version="4.5.3"; +Export-Package: org.eclipse.jgit.ant.tasks;version="4.6.2"; 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 3a3052eb93..194c9dde27 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.5.3-SNAPSHOT</version> + <version>4.6.2-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.ant</artifactId> diff --git a/org.eclipse.jgit.ant/src/org/eclipse/jgit/ant/tasks/GitAddTask.java b/org.eclipse.jgit.ant/src/org/eclipse/jgit/ant/tasks/GitAddTask.java index b9a868826e..db6f008a10 100644 --- a/org.eclipse.jgit.ant/src/org/eclipse/jgit/ant/tasks/GitAddTask.java +++ b/org.eclipse.jgit.ant/src/org/eclipse/jgit/ant/tasks/GitAddTask.java @@ -53,9 +53,10 @@ import org.apache.tools.ant.types.FileSet; import org.apache.tools.ant.types.resources.Union; import org.eclipse.jgit.api.AddCommand; import org.eclipse.jgit.api.Git; -import org.eclipse.jgit.storage.file.FileRepositoryBuilder; +import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.RepositoryCache; +import org.eclipse.jgit.storage.file.FileRepositoryBuilder; import org.eclipse.jgit.util.FS; /** @@ -135,7 +136,7 @@ public class GitAddTask extends Task { gitAdd.addFilepattern(toAdd); } gitAdd.call(); - } catch (Exception e) { + } catch (IOException | GitAPIException e) { throw new BuildException("Could not add files to index." + src, e); } diff --git a/org.eclipse.jgit.ant/src/org/eclipse/jgit/ant/tasks/GitCloneTask.java b/org.eclipse.jgit.ant/src/org/eclipse/jgit/ant/tasks/GitCloneTask.java index f23f3b753d..b2cb35cbef 100644 --- a/org.eclipse.jgit.ant/src/org/eclipse/jgit/ant/tasks/GitCloneTask.java +++ b/org.eclipse.jgit.ant/src/org/eclipse/jgit/ant/tasks/GitCloneTask.java @@ -49,12 +49,14 @@ import org.apache.tools.ant.Project; import org.apache.tools.ant.Task; import org.eclipse.jgit.api.CloneCommand; import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.api.errors.GitAPIException; +import org.eclipse.jgit.api.errors.JGitInternalException; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.transport.URIish; /** * Clone a repository into a new directory. - * + * * @see <a href="http://www.kernel.org/pub/software/scm/git/docs/git-clone.html" * >git-clone(1)</a> */ @@ -76,9 +78,9 @@ public class GitCloneTask extends Task { /** * The optional directory associated with the clone operation. If the * directory isn't set, a name associated with the source uri will be used. - * + * * @see URIish#getHumanishName() - * + * * @param destination * the directory to clone to */ @@ -105,12 +107,12 @@ public class GitCloneTask extends Task { @Override public void execute() throws BuildException { log("Cloning repository " + uri); - + CloneCommand clone = Git.cloneRepository(); try { clone.setURI(uri).setDirectory(destination).setBranch(branch).setBare(bare); clone.call().getRepository().close(); - } catch (Exception e) { + } catch (GitAPIException | JGitInternalException e) { log("Could not clone repository: " + e, e, Project.MSG_ERR); throw new BuildException("Could not clone repository: " + e.getMessage(), e); } diff --git a/org.eclipse.jgit.archive/.classpath b/org.eclipse.jgit.archive/.classpath index 3bc247511f..22f30643cb 100644 --- a/org.eclipse.jgit.archive/.classpath +++ b/org.eclipse.jgit.archive/.classpath @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <classpath> <classpathentry kind="src" path="src"/> - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> <classpathentry kind="output" path="bin"/> </classpath> 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 bfaf736d6e..4f1759fb3f 100644 --- a/org.eclipse.jgit.archive/.settings/org.eclipse.jdt.core.prefs +++ b/org.eclipse.jgit.archive/.settings/org.eclipse.jdt.core.prefs @@ -7,9 +7,9 @@ org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jgit.annotations.N org.eclipse.jdt.core.compiler.annotation.nullanalysis=enabled org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.7 +org.eclipse.jdt.core.compiler.compliance=1.8 org.eclipse.jdt.core.compiler.debug.lineNumber=generate org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.debug.sourceFile=generate @@ -112,7 +112,7 @@ org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=error -org.eclipse.jdt.core.compiler.source=1.7 +org.eclipse.jdt.core.compiler.source=1.8 org.eclipse.jdt.core.formatter.align_type_members_on_columns=false org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 diff --git a/org.eclipse.jgit.archive/META-INF/MANIFEST.MF b/org.eclipse.jgit.archive/META-INF/MANIFEST.MF index e3f8d6c46c..b2fe6b2659 100644 --- a/org.eclipse.jgit.archive/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.archive/META-INF/MANIFEST.MF @@ -2,24 +2,24 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Bundle-SymbolicName: org.eclipse.jgit.archive -Bundle-Version: 4.5.3.qualifier +Bundle-Version: 4.6.2.qualifier Bundle-Vendor: %provider_name Bundle-Localization: plugin -Bundle-RequiredExecutionEnvironment: JavaSE-1.7 +Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Import-Package: org.apache.commons.compress.archivers;version="[1.4,2.0)", org.apache.commons.compress.archivers.tar;version="[1.4,2.0)", org.apache.commons.compress.archivers.zip;version="[1.4,2.0)", 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.5.3,4.6.0)", - org.eclipse.jgit.lib;version="[4.5.3,4.6.0)", - org.eclipse.jgit.nls;version="[4.5.3,4.6.0)", - org.eclipse.jgit.util;version="[4.5.3,4.6.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.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.5.3"; +Export-Package: org.eclipse.jgit.archive;version="4.6.2"; 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 0230bf9cce..7d7477c4b3 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-ManifestVersion: 2 Bundle-Name: org.eclipse.jgit.archive - Sources Bundle-SymbolicName: org.eclipse.jgit.archive.source Bundle-Vendor: Eclipse.org - JGit -Bundle-Version: 4.5.3.qualifier -Eclipse-SourceBundle: org.eclipse.jgit.archive;version="4.5.3.qualifier";roots="." +Bundle-Version: 4.6.2.qualifier +Eclipse-SourceBundle: org.eclipse.jgit.archive;version="4.6.2.qualifier";roots="." diff --git a/org.eclipse.jgit.archive/pom.xml b/org.eclipse.jgit.archive/pom.xml index 4f879458f7..9c3881758f 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.5.3-SNAPSHOT</version> + <version>4.6.2-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.archive</artifactId> diff --git a/org.eclipse.jgit.http.apache/.classpath b/org.eclipse.jgit.http.apache/.classpath index a14ade4efd..110168ffa1 100644 --- a/org.eclipse.jgit.http.apache/.classpath +++ b/org.eclipse.jgit.http.apache/.classpath @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <classpath> - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> <classpathentry kind="src" path="src"/> <classpathentry kind="src" path="resources"/> 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 cd620c394e..80cfbbbd3b 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 @@ -7,9 +7,9 @@ org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nul org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.7 +org.eclipse.jdt.core.compiler.compliance=1.8 org.eclipse.jdt.core.compiler.debug.lineNumber=generate org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.debug.sourceFile=generate @@ -112,7 +112,7 @@ org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=error -org.eclipse.jdt.core.compiler.source=1.7 +org.eclipse.jdt.core.compiler.source=1.8 org.eclipse.jdt.core.formatter.align_type_members_on_columns=false org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 diff --git a/org.eclipse.jgit.http.apache/META-INF/MANIFEST.MF b/org.eclipse.jgit.http.apache/META-INF/MANIFEST.MF index fa1d6f11b5..978be2795b 100644 --- a/org.eclipse.jgit.http.apache/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.http.apache/META-INF/MANIFEST.MF @@ -2,30 +2,36 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %Bundle-Name Bundle-SymbolicName: org.eclipse.jgit.http.apache -Bundle-Version: 4.5.3.qualifier -Bundle-RequiredExecutionEnvironment: JavaSE-1.7 +Bundle-Version: 4.6.2.qualifier +Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Bundle-Localization: plugin Bundle-Vendor: %Provider-Name Bundle-ActivationPolicy: lazy -Import-Package: org.apache.http;version="[4.1.0,5.0.0)", - org.apache.http.client;version="[4.1.0,5.0.0)", - org.apache.http.client.methods;version="[4.1.0,5.0.0)", - org.apache.http.client.params;version="[4.1.0,5.0.0)", - org.apache.http.conn;version="[4.1.0,5.0.0)", - org.apache.http.conn.params;version="[4.1.0,5.0.0)", - org.apache.http.conn.scheme;version="[4.1.0,5.0.0)", - org.apache.http.conn.ssl;version="[4.1.0,5.0.0)", - org.apache.http.entity;version="[4.1.0,5.0.0)", - org.apache.http.impl.client;version="[4.1.0,5.0.0)", - org.apache.http.impl.client.cache;version="[4.1.0,5.0.0)", - org.apache.http.params;version="[4.1.0,5.0.0)", - org.eclipse.jgit.nls;version="[4.5.3,4.6.0)", - org.eclipse.jgit.transport.http;version="[4.5.3,4.6.0)", - org.eclipse.jgit.util;version="[4.5.3,4.6.0)" -Export-Package: org.eclipse.jgit.transport.http.apache;version="4.5.3"; - uses:="org.eclipse.jgit.transport.http, - javax.net.ssl, - org.apache.http.client, +Import-Package: org.apache.http;version="[4.3.0,5.0.0)", + org.apache.http.client;version="[4.3.0,5.0.0)", + org.apache.http.client.config;version="[4.3.0,5.0.0)", + org.apache.http.client.methods;version="[4.3.0,5.0.0)", + org.apache.http.client.params;version="[4.3.0,5.0.0)", + org.apache.http.config;version="[4.3.0,5.0.0)", + org.apache.http.conn;version="[4.3.0,5.0.0)", + org.apache.http.conn.params;version="[4.3.0,5.0.0)", + org.apache.http.conn.scheme;version="[4.3.0,5.0.0)", + org.apache.http.conn.socket;version="[4.3.0,5.0.0)", + 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"; + uses:="org.apache.http.client, + org.eclipse.jgit.transport.http, + org.apache.http.entity, org.apache.http.client.methods, + javax.net.ssl, + org.eclipse.jgit.util, org.apache.http", org.eclipse.jgit.transport.http.apache.internal;x-internal:=true diff --git a/org.eclipse.jgit.http.apache/pom.xml b/org.eclipse.jgit.http.apache/pom.xml index 7c2de007ac..dfd8585b76 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.5.3-SNAPSHOT</version> + <version>4.6.2-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.http.apache</artifactId> diff --git a/org.eclipse.jgit.http.apache/src/org/eclipse/jgit/transport/http/apache/HttpClientConnection.java b/org.eclipse.jgit.http.apache/src/org/eclipse/jgit/transport/http/apache/HttpClientConnection.java index 2d9d17a890..281154fb1a 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 @@ -80,19 +80,21 @@ import org.apache.http.HttpHost; import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; +import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpHead; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPut; import org.apache.http.client.methods.HttpUriRequest; -import org.apache.http.client.params.ClientPNames; -import org.apache.http.conn.params.ConnRoutePNames; -import org.apache.http.conn.scheme.Scheme; -import org.apache.http.conn.ssl.SSLSocketFactory; +import org.apache.http.config.Registry; +import org.apache.http.config.RegistryBuilder; +import org.apache.http.conn.socket.ConnectionSocketFactory; +import org.apache.http.conn.socket.PlainConnectionSocketFactory; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.conn.ssl.X509HostnameVerifier; -import org.apache.http.impl.client.DefaultHttpClient; -import org.apache.http.params.CoreConnectionPNames; -import org.apache.http.params.HttpParams; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.impl.conn.BasicHttpClientConnectionManager; import org.eclipse.jgit.transport.http.HttpConnection; import org.eclipse.jgit.transport.http.apache.internal.HttpApacheText; import org.eclipse.jgit.util.TemporaryBuffer; @@ -131,29 +133,39 @@ public class HttpClientConnection implements HttpConnection { SSLContext ctx; private HttpClient getClient() { - if (client == null) - client = new DefaultHttpClient(); - HttpParams params = client.getParams(); - if (proxy != null && !Proxy.NO_PROXY.equals(proxy)) { - isUsingProxy = true; - InetSocketAddress adr = (InetSocketAddress) proxy.address(); - params.setParameter(ConnRoutePNames.DEFAULT_PROXY, - new HttpHost(adr.getHostName(), adr.getPort())); - } - if (timeout != null) - params.setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, - timeout.intValue()); - if (readTimeout != null) - params.setIntParameter(CoreConnectionPNames.SO_TIMEOUT, - readTimeout.intValue()); - if (followRedirects != null) - params.setBooleanParameter(ClientPNames.HANDLE_REDIRECTS, - followRedirects.booleanValue()); - if (hostnameverifier != null) { - SSLSocketFactory sf; - sf = new SSLSocketFactory(getSSLContext(), hostnameverifier); - Scheme https = new Scheme("https", 443, sf); //$NON-NLS-1$ - client.getConnectionManager().getSchemeRegistry().register(https); + if (client == null) { + HttpClientBuilder clientBuilder = HttpClients.custom(); + RequestConfig.Builder configBuilder = RequestConfig.custom(); + if (proxy != null && !Proxy.NO_PROXY.equals(proxy)) { + isUsingProxy = true; + InetSocketAddress adr = (InetSocketAddress) proxy.address(); + clientBuilder.setProxy( + new HttpHost(adr.getHostName(), adr.getPort())); + } + if (timeout != null) { + configBuilder.setConnectTimeout(timeout.intValue()); + } + if (readTimeout != null) { + configBuilder.setSocketTimeout(readTimeout.intValue()); + } + if (followRedirects != null) { + configBuilder + .setRedirectsEnabled(followRedirects.booleanValue()); + } + if (hostnameverifier != null) { + SSLConnectionSocketFactory sslConnectionFactory = new SSLConnectionSocketFactory( + getSSLContext(), hostnameverifier); + clientBuilder.setSSLSocketFactory(sslConnectionFactory); + Registry<ConnectionSocketFactory> registry = RegistryBuilder + .<ConnectionSocketFactory> create() + .register("https", sslConnectionFactory) + .register("http", PlainConnectionSocketFactory.INSTANCE) + .build(); + clientBuilder.setConnectionManager( + new BasicHttpClientConnectionManager(registry)); + } + clientBuilder.setDefaultRequestConfig(configBuilder.build()); + client = clientBuilder.build(); } return client; @@ -283,11 +295,11 @@ public class HttpClientConnection implements HttpConnection { } public void setConnectTimeout(int timeout) { - this.timeout = new Integer(timeout); + this.timeout = Integer.valueOf(timeout); } public void setReadTimeout(int readTimeout) { - this.readTimeout = new Integer(readTimeout); + this.readTimeout = Integer.valueOf(readTimeout); } public String getContentType() { @@ -311,12 +323,21 @@ public class HttpClientConnection implements HttpConnection { } public int getContentLength() { - return Integer.parseInt(resp.getFirstHeader("content-length") //$NON-NLS-1$ - .getValue()); + Header contentLength = resp.getFirstHeader("content-length"); //$NON-NLS-1$ + if (contentLength == null) { + return -1; + } + + try { + int l = Integer.parseInt(contentLength.getValue()); + return l < 0 ? -1 : l; + } catch (NumberFormatException e) { + return -1; + } } public void setInstanceFollowRedirects(boolean followRedirects) { - this.followRedirects = new Boolean(followRedirects); + this.followRedirects = Boolean.valueOf(followRedirects); } public void setDoOutput(boolean dooutput) { 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 377e5ca572..93328c96ca 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 @@ -105,7 +105,7 @@ public class TemporaryBufferEntity extends AbstractHttpEntity * @param contentLength */ public void setContentLength(int contentLength) { - this.contentLength = new Integer(contentLength); + this.contentLength = Integer.valueOf(contentLength); } /** diff --git a/org.eclipse.jgit.http.server/.classpath b/org.eclipse.jgit.http.server/.classpath index 04a2be7bdb..cfcf24a51e 100644 --- a/org.eclipse.jgit.http.server/.classpath +++ b/org.eclipse.jgit.http.server/.classpath @@ -2,7 +2,7 @@ <classpath> <classpathentry kind="src" path="src"/> <classpathentry kind="src" path="resources"/> - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> <classpathentry kind="output" path="bin"/> </classpath> 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 cd620c394e..80cfbbbd3b 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 @@ -7,9 +7,9 @@ org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nul org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.7 +org.eclipse.jdt.core.compiler.compliance=1.8 org.eclipse.jdt.core.compiler.debug.lineNumber=generate org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.debug.sourceFile=generate @@ -112,7 +112,7 @@ org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=error -org.eclipse.jdt.core.compiler.source=1.7 +org.eclipse.jdt.core.compiler.source=1.8 org.eclipse.jdt.core.formatter.align_type_members_on_columns=false org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 diff --git a/org.eclipse.jgit.http.server/META-INF/MANIFEST.MF b/org.eclipse.jgit.http.server/META-INF/MANIFEST.MF index 6e9422dcac..be3bb333bd 100644 --- a/org.eclipse.jgit.http.server/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.http.server/META-INF/MANIFEST.MF @@ -2,27 +2,27 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Bundle-SymbolicName: org.eclipse.jgit.http.server -Bundle-Version: 4.5.3.qualifier +Bundle-Version: 4.6.2.qualifier Bundle-Localization: plugin Bundle-Vendor: %provider_name -Export-Package: org.eclipse.jgit.http.server;version="4.5.3", - org.eclipse.jgit.http.server.glue;version="4.5.3"; +Export-Package: org.eclipse.jgit.http.server;version="4.6.2", + org.eclipse.jgit.http.server.glue;version="4.6.2"; uses:="javax.servlet,javax.servlet.http", - org.eclipse.jgit.http.server.resolver;version="4.5.3"; + org.eclipse.jgit.http.server.resolver;version="4.6.2"; uses:="org.eclipse.jgit.transport.resolver, org.eclipse.jgit.lib, org.eclipse.jgit.transport, javax.servlet.http" Bundle-ActivationPolicy: lazy -Bundle-RequiredExecutionEnvironment: JavaSE-1.7 +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.5.3,4.6.0)", - org.eclipse.jgit.internal.storage.dfs;version="[4.5.3,4.6.0)", - org.eclipse.jgit.internal.storage.file;version="[4.5.3,4.6.0)", - org.eclipse.jgit.lib;version="[4.5.3,4.6.0)", - org.eclipse.jgit.nls;version="[4.5.3,4.6.0)", - org.eclipse.jgit.revwalk;version="[4.5.3,4.6.0)", - org.eclipse.jgit.transport;version="[4.5.3,4.6.0)", - org.eclipse.jgit.transport.resolver;version="[4.5.3,4.6.0)", - org.eclipse.jgit.util;version="[4.5.3,4.6.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)" diff --git a/org.eclipse.jgit.http.server/pom.xml b/org.eclipse.jgit.http.server/pom.xml index 0d685d3d52..843ec4bf72 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.5.3-SNAPSHOT</version> + <version>4.6.2-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.http.server</artifactId> diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/GitSmartHttpTools.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/GitSmartHttpTools.java index d8cd61df81..03c9d8da69 100644 --- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/GitSmartHttpTools.java +++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/GitSmartHttpTools.java @@ -43,15 +43,15 @@ package org.eclipse.jgit.http.server; +import static javax.servlet.http.HttpServletResponse.SC_FORBIDDEN; +import static javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR; +import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND; import static org.eclipse.jgit.http.server.ServletUtils.ATTRIBUTE_HANDLER; +import static org.eclipse.jgit.transport.GitProtocolConstants.CAPABILITY_SIDE_BAND_64K; import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_SIDE_BAND; import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_SIDE_BAND_64K; -import static org.eclipse.jgit.transport.GitProtocolConstants.CAPABILITY_SIDE_BAND_64K; import static org.eclipse.jgit.transport.SideBandOutputStream.CH_ERROR; import static org.eclipse.jgit.transport.SideBandOutputStream.SMALL_BUF; -import static javax.servlet.http.HttpServletResponse.SC_FORBIDDEN; -import static javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR; -import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND; import java.io.ByteArrayOutputStream; import java.io.IOException; diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ServletUtils.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ServletUtils.java index 042ccf3dd7..1336d6e939 100644 --- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ServletUtils.java +++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/ServletUtils.java @@ -44,6 +44,7 @@ package org.eclipse.jgit.http.server; import static org.eclipse.jgit.util.HttpSupport.ENCODING_GZIP; +import static org.eclipse.jgit.util.HttpSupport.ENCODING_X_GZIP; 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_ETAG; @@ -111,7 +112,7 @@ public final class ServletUtils { throws IOException { InputStream in = req.getInputStream(); final String enc = req.getHeader(HDR_CONTENT_ENCODING); - if (ENCODING_GZIP.equals(enc) || "x-gzip".equals(enc)) //$NON-NLS-1$ + if (ENCODING_GZIP.equals(enc) || ENCODING_X_GZIP.equals(enc)) //$NON-NLS-1$ in = new GZIPInputStream(in); else if (enc != null) throw new IOException(MessageFormat.format(HttpServerText.get().encodingNotSupportedByThisLibrary 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 2d466e2bc8..2414660a06 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 @@ -43,6 +43,8 @@ package org.eclipse.jgit.http.server.glue; +import static java.lang.Integer.valueOf; + import java.io.IOException; import java.text.MessageFormat; @@ -53,8 +55,6 @@ import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; -import static java.lang.Integer.valueOf; - import org.eclipse.jgit.http.server.HttpServerText; /** diff --git a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/WrappedRequest.java b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/WrappedRequest.java index 7f8da7c440..b702c07486 100644 --- a/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/WrappedRequest.java +++ b/org.eclipse.jgit.http.server/src/org/eclipse/jgit/http/server/glue/WrappedRequest.java @@ -72,7 +72,7 @@ public class WrappedRequest extends HttpServletRequestWrapper { @Override public String getPathTranslated() { final String p = getPathInfo(); - return p != null ? getRealPath(p) : null; + return p != null ? getSession().getServletContext().getRealPath(p) : null; } @Override 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 43a7e246d6..4ef2a7c4cb 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 @@ -47,8 +47,8 @@ import javax.servlet.http.HttpServletRequest; import org.eclipse.jgit.http.server.GitServlet; import org.eclipse.jgit.lib.Config; -import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.Config.SectionParser; +import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException; import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; 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 df876ba436..8c39b7997b 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 @@ -46,9 +46,9 @@ package org.eclipse.jgit.http.server.resolver; import javax.servlet.http.HttpServletRequest; import org.eclipse.jgit.lib.Config; +import org.eclipse.jgit.lib.Config.SectionParser; import org.eclipse.jgit.lib.PersonIdent; import org.eclipse.jgit.lib.Repository; -import org.eclipse.jgit.lib.Config.SectionParser; import org.eclipse.jgit.transport.ReceivePack; import org.eclipse.jgit.transport.resolver.ReceivePackFactory; import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException; 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 76f40c58a9..34c069e0e1 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 @@ -46,8 +46,8 @@ package org.eclipse.jgit.http.server.resolver; import javax.servlet.http.HttpServletRequest; import org.eclipse.jgit.lib.Config; -import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.Config.SectionParser; +import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.transport.UploadPack; import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException; import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; diff --git a/org.eclipse.jgit.http.test/.classpath b/org.eclipse.jgit.http.test/.classpath index e1a1a64a49..e6014c7122 100644 --- a/org.eclipse.jgit.http.test/.classpath +++ b/org.eclipse.jgit.http.test/.classpath @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <classpath> - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> <classpathentry kind="src" path="tst"/> <classpathentry kind="src" path="src"/> 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 87210fb160..10c29d5576 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 @@ -7,9 +7,9 @@ org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nul org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.7 +org.eclipse.jdt.core.compiler.compliance=1.8 org.eclipse.jdt.core.compiler.debug.lineNumber=generate org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.debug.sourceFile=generate @@ -112,7 +112,7 @@ org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=error -org.eclipse.jdt.core.compiler.source=1.7 +org.eclipse.jdt.core.compiler.source=1.8 org.eclipse.jdt.core.formatter.align_type_members_on_columns=false org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 diff --git a/org.eclipse.jgit.http.test/BUCK b/org.eclipse.jgit.http.test/BUCK index d65cdadfc2..f5cd10e58b 100644 --- a/org.eclipse.jgit.http.test/BUCK +++ b/org.eclipse.jgit.http.test/BUCK @@ -25,7 +25,7 @@ for t in TESTS: '//lib/jetty:util', '//lib:commons-logging', ], - source_under_test = ['//org.eclipse.jgit.http.server:jgit-servlet'], + vm_args = ['-Djava.io.tmpdir=buck-out'], ) java_library( diff --git a/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF index bc8f08eba4..6effed6f95 100644 --- a/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF @@ -2,44 +2,44 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Bundle-SymbolicName: org.eclipse.jgit.http.test -Bundle-Version: 4.5.3.qualifier +Bundle-Version: 4.6.2.qualifier Bundle-Vendor: %provider_name Bundle-Localization: plugin -Bundle-RequiredExecutionEnvironment: JavaSE-1.7 +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.jetty.continuation;version="[9.0.0,10.0.0)", - org.eclipse.jetty.http;version="[9.0.0,10.0.0)", - org.eclipse.jetty.io;version="[9.0.0,10.0.0)", - org.eclipse.jetty.security;version="[9.0.0,10.0.0)", - org.eclipse.jetty.security.authentication;version="[9.0.0,10.0.0)", - org.eclipse.jetty.server;version="[9.0.0,10.0.0)", - org.eclipse.jetty.server.handler;version="[9.0.0,10.0.0)", - org.eclipse.jetty.server.nio;version="[9.0.0,10.0.0)", - org.eclipse.jetty.servlet;version="[9.0.0,10.0.0)", - org.eclipse.jetty.util;version="[9.0.0,10.0.0)", - org.eclipse.jetty.util.component;version="[9.0.0,10.0.0)", - org.eclipse.jetty.util.log;version="[9.0.0,10.0.0)", - org.eclipse.jetty.util.security;version="[9.0.0,10.0.0)", - org.eclipse.jetty.util.thread;version="[9.0.0,10.0.0)", - org.eclipse.jgit.errors;version="[4.5.3,4.6.0)", - org.eclipse.jgit.http.server;version="[4.5.3,4.6.0)", - org.eclipse.jgit.http.server.glue;version="[4.5.3,4.6.0)", - org.eclipse.jgit.http.server.resolver;version="[4.5.3,4.6.0)", - org.eclipse.jgit.internal;version="[4.5.3,4.6.0)", - org.eclipse.jgit.internal.storage.dfs;version="[4.5.3,4.6.0)", - org.eclipse.jgit.internal.storage.file;version="[4.5.3,4.6.0)", - org.eclipse.jgit.junit;version="[4.5.3,4.6.0)", - org.eclipse.jgit.junit.http;version="[4.5.3,4.6.0)", - org.eclipse.jgit.lib;version="[4.5.3,4.6.0)", - org.eclipse.jgit.nls;version="[4.5.3,4.6.0)", - org.eclipse.jgit.revwalk;version="[4.5.3,4.6.0)", - org.eclipse.jgit.storage.file;version="[4.5.3,4.6.0)", - org.eclipse.jgit.transport;version="[4.5.3,4.6.0)", - org.eclipse.jgit.transport.http;version="[4.5.3,4.6.0)", - org.eclipse.jgit.transport.http.apache;version="[4.5.3,4.6.0)", - org.eclipse.jgit.transport.resolver;version="[4.5.3,4.6.0)", - org.eclipse.jgit.util;version="[4.5.3,4.6.0)", + org.eclipse.jetty.continuation;version="[9.0.0,9.4.0)", + org.eclipse.jetty.http;version="[9.0.0,9.4.0)", + org.eclipse.jetty.io;version="[9.0.0,9.4.0)", + org.eclipse.jetty.security;version="[9.0.0,9.4.0)", + org.eclipse.jetty.security.authentication;version="[9.0.0,9.4.0)", + org.eclipse.jetty.server;version="[9.0.0,9.4.0)", + org.eclipse.jetty.server.handler;version="[9.0.0,9.4.0)", + org.eclipse.jetty.server.nio;version="[9.0.0,9.4.0)", + org.eclipse.jetty.servlet;version="[9.0.0,9.4.0)", + org.eclipse.jetty.util;version="[9.0.0,9.4.0)", + 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.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.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 8ce1aa2e6a..0366f757b6 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.5.3-SNAPSHOT</version> + <version>4.6.2-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.http.test</artifactId> @@ -60,7 +60,9 @@ <description> Tests for the HTTP transport. </description> - + <properties> + <maven.javadoc.skip>true</maven.javadoc.skip> + </properties> <dependencies> <dependency> <groupId>junit</groupId> diff --git a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/server/ClientVersionUtilTest.java b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/server/ClientVersionUtilTest.java index a8c604ce65..c7260e325b 100644 --- a/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/server/ClientVersionUtilTest.java +++ b/org.eclipse.jgit.http.test/tst/org/eclipse/jgit/http/server/ClientVersionUtilTest.java @@ -43,11 +43,11 @@ package org.eclipse.jgit.http.server; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; import static org.eclipse.jgit.http.server.ClientVersionUtil.hasPushStatusBug; import static org.eclipse.jgit.http.server.ClientVersionUtil.invalidVersion; import static org.eclipse.jgit.http.server.ClientVersionUtil.parseVersion; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import org.junit.Assert; import org.junit.Test; 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 da3a09809b..bce44f9bf3 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 @@ -199,7 +199,7 @@ public class DumbClientSmartServerTest extends HttpTestCase { .startsWith("JGit/")); assertEquals("*/*", info.getRequestHeader(HDR_ACCEPT)); assertEquals(200, info.getStatus()); - assertEquals("text/plain; charset=UTF-8", + assertEquals("text/plain;charset=utf-8", info .getResponseHeader(HDR_CONTENT_TYPE)); @@ -269,7 +269,7 @@ public class DumbClientSmartServerTest extends HttpTestCase { assertEquals("GET", req.get(0).getMethod()); assertEquals(0, req.get(0).getParameters().size()); assertEquals(200, req.get(0).getStatus()); - assertEquals("text/plain; charset=UTF-8", + assertEquals("text/plain;charset=utf-8", req.get(0).getResponseHeader( HDR_CONTENT_TYPE)); } 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 2b9105cfe7..3e882719b3 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 @@ -454,7 +454,7 @@ public class SmartClientSmartServerTest extends HttpTestCase { } catch (TransportException err) { String exp = brokenURI + ": expected" + " Content-Type application/x-git-upload-pack-result;" - + " received Content-Type text/plain; charset=UTF-8"; + + " received Content-Type text/plain;charset=utf-8"; assertEquals(exp, err.getMessage()); } } @@ -476,7 +476,7 @@ public class SmartClientSmartServerTest extends HttpTestCase { assertEquals(join(brokenURI, "git-upload-pack"), service.getPath()); assertEquals(0, service.getParameters().size()); assertEquals(200, service.getStatus()); - assertEquals("text/plain; charset=UTF-8", + assertEquals("text/plain;charset=utf-8", service.getResponseHeader(HDR_CONTENT_TYPE)); } diff --git a/org.eclipse.jgit.junit.http/.classpath b/org.eclipse.jgit.junit.http/.classpath index b1dabee382..b862a296d3 100644 --- a/org.eclipse.jgit.junit.http/.classpath +++ b/org.eclipse.jgit.junit.http/.classpath @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?>
<classpath>
- <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="bin"/>
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 87210fb160..10c29d5576 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 @@ -7,9 +7,9 @@ org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nul org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.7 +org.eclipse.jdt.core.compiler.compliance=1.8 org.eclipse.jdt.core.compiler.debug.lineNumber=generate org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.debug.sourceFile=generate @@ -112,7 +112,7 @@ org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=error -org.eclipse.jdt.core.compiler.source=1.7 +org.eclipse.jdt.core.compiler.source=1.8 org.eclipse.jdt.core.formatter.align_type_members_on_columns=false org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 diff --git a/org.eclipse.jgit.junit.http/META-INF/MANIFEST.MF b/org.eclipse.jgit.junit.http/META-INF/MANIFEST.MF index fb080db41d..cd42e2c117 100644 --- a/org.eclipse.jgit.junit.http/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.junit.http/META-INF/MANIFEST.MF @@ -2,34 +2,34 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Bundle-SymbolicName: org.eclipse.jgit.junit.http -Bundle-Version: 4.5.3.qualifier +Bundle-Version: 4.6.2.qualifier Bundle-Localization: plugin Bundle-Vendor: %provider_name Bundle-ActivationPolicy: lazy -Bundle-RequiredExecutionEnvironment: JavaSE-1.7 +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.apache.commons.logging;version="[1.1.1,2.0.0)", - org.eclipse.jetty.http;version="[9.0.0,10.0.0)", - org.eclipse.jetty.security;version="[9.0.0,10.0.0)", - org.eclipse.jetty.security.authentication;version="[9.0.0,10.0.0)", - org.eclipse.jetty.server;version="[9.0.0,10.0.0)", - org.eclipse.jetty.server.handler;version="[9.0.0,10.0.0)", - org.eclipse.jetty.server.nio;version="[9.0.0,10.0.0)", - org.eclipse.jetty.servlet;version="[9.0.0,10.0.0)", - org.eclipse.jetty.util.component;version="[9.0.0,10.0.0)", - org.eclipse.jetty.util.log;version="[9.0.0,10.0.0)", - org.eclipse.jetty.util.security;version="[9.0.0,10.0.0)", - org.eclipse.jgit.errors;version="[4.5.3,4.6.0)", - org.eclipse.jgit.http.server;version="[4.5.3,4.6.0)", - org.eclipse.jgit.internal.storage.file;version="[4.5.3,4.6.0)", - org.eclipse.jgit.junit;version="[4.5.3,4.6.0)", - org.eclipse.jgit.lib;version="[4.5.3,4.6.0)", - org.eclipse.jgit.revwalk;version="[4.5.3,4.6.0)", - org.eclipse.jgit.transport;version="[4.5.3,4.6.0)", - org.eclipse.jgit.transport.resolver;version="[4.5.3,4.6.0)", + org.eclipse.jetty.http;version="[9.0.0,9.4.0)", + org.eclipse.jetty.security;version="[9.0.0,9.4.0)", + org.eclipse.jetty.security.authentication;version="[9.0.0,9.4.0)", + org.eclipse.jetty.server;version="[9.0.0,9.4.0)", + org.eclipse.jetty.server.handler;version="[9.0.0,9.4.0)", + org.eclipse.jetty.server.nio;version="[9.0.0,9.4.0)", + org.eclipse.jetty.servlet;version="[9.0.0,9.4.0)", + 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.junit;version="[4.0.0,5.0.0)" -Export-Package: org.eclipse.jgit.junit.http;version="4.5.3"; +Export-Package: org.eclipse.jgit.junit.http;version="4.6.2"; uses:="org.eclipse.jgit.transport, org.eclipse.jgit.junit, javax.servlet.http, diff --git a/org.eclipse.jgit.junit.http/pom.xml b/org.eclipse.jgit.junit.http/pom.xml index 685a5ee6a3..ced9c2c14f 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.5.3-SNAPSHOT</version> + <version>4.6.2-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.junit.http</artifactId> diff --git a/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/AppServer.java b/org.eclipse.jgit.junit.http/src/org/eclipse/jgit/junit/http/AppServer.java index cca4f43dbd..44c1977171 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 @@ -185,13 +185,11 @@ public class AppServer { putUser(username, new Password(password), new String[] { role }); } - protected String[] loadRoleInfo( - @SuppressWarnings("unused") KnownUser user) { + protected String[] loadRoleInfo(KnownUser user) { return null; } - protected KnownUser loadUserInfo( - @SuppressWarnings("unused") String usrname) { + protected KnownUser loadUserInfo(String usrname) { return null; } } diff --git a/org.eclipse.jgit.junit/.classpath b/org.eclipse.jgit.junit/.classpath index 098194ca4b..eca7bdba8f 100644 --- a/org.eclipse.jgit.junit/.classpath +++ b/org.eclipse.jgit.junit/.classpath @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <classpath> - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> <classpathentry kind="src" path="src"/> <classpathentry kind="output" path="bin"/> 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 87210fb160..10c29d5576 100644 --- a/org.eclipse.jgit.junit/.settings/org.eclipse.jdt.core.prefs +++ b/org.eclipse.jgit.junit/.settings/org.eclipse.jdt.core.prefs @@ -7,9 +7,9 @@ org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nul org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.7 +org.eclipse.jdt.core.compiler.compliance=1.8 org.eclipse.jdt.core.compiler.debug.lineNumber=generate org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.debug.sourceFile=generate @@ -112,7 +112,7 @@ org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=error -org.eclipse.jdt.core.compiler.source=1.7 +org.eclipse.jdt.core.compiler.source=1.8 org.eclipse.jdt.core.formatter.align_type_members_on_columns=false org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 diff --git a/org.eclipse.jgit.junit/META-INF/MANIFEST.MF b/org.eclipse.jgit.junit/META-INF/MANIFEST.MF index e16b8bed4f..9de6239890 100644 --- a/org.eclipse.jgit.junit/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.junit/META-INF/MANIFEST.MF @@ -2,30 +2,31 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Bundle-SymbolicName: org.eclipse.jgit.junit -Bundle-Version: 4.5.3.qualifier +Bundle-Version: 4.6.2.qualifier Bundle-Localization: plugin Bundle-Vendor: %provider_name Bundle-ActivationPolicy: lazy -Bundle-RequiredExecutionEnvironment: JavaSE-1.7 -Import-Package: org.eclipse.jgit.api;version="[4.5.3,4.6.0)", - org.eclipse.jgit.api.errors;version="[4.5.3,4.6.0)", - org.eclipse.jgit.dircache;version="[4.5.3,4.6.0)", - org.eclipse.jgit.errors;version="[4.5.3,4.6.0)", - org.eclipse.jgit.internal.storage.file;version="[4.5.3,4.6.0)", - org.eclipse.jgit.internal.storage.pack;version="[4.5.3,4.6.0)", - org.eclipse.jgit.lib;version="[4.5.3,4.6.0)", - org.eclipse.jgit.merge;version="[4.5.3,4.6.0)", - org.eclipse.jgit.revwalk;version="[4.5.3,4.6.0)", - org.eclipse.jgit.storage.file;version="[4.5.3,4.6.0)", - org.eclipse.jgit.treewalk;version="[4.5.3,4.6.0)", - org.eclipse.jgit.treewalk.filter;version="[4.5.3,4.6.0)", - org.eclipse.jgit.util;version="[4.5.3,4.6.0)", - org.eclipse.jgit.util.io;version="[4.5.3,4.6.0)", +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)", 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.5.3"; +Export-Package: org.eclipse.jgit.junit;version="4.6.2"; uses:="org.eclipse.jgit.dircache, org.eclipse.jgit.lib, org.eclipse.jgit.revwalk, @@ -33,4 +34,5 @@ Export-Package: org.eclipse.jgit.junit;version="4.5.3"; org.eclipse.jgit.treewalk, org.eclipse.jgit.util, org.eclipse.jgit.storage.file, - org.eclipse.jgit.api" + org.eclipse.jgit.api", + org.eclipse.jgit.junit.time;version="4.6.2" diff --git a/org.eclipse.jgit.junit/pom.xml b/org.eclipse.jgit.junit/pom.xml index 37c60ca4b4..ab757afd9a 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.5.3-SNAPSHOT</version> + <version>4.6.2-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 4d713b5e73..dc2e8bfb71 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 @@ -50,12 +50,21 @@ import static org.junit.Assert.fail; import java.io.File; import java.io.IOException; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +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.*; +import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.lib.PersonIdent; +import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.lib.RepositoryCache; import org.eclipse.jgit.storage.file.FileBasedConfig; import org.eclipse.jgit.storage.file.WindowCacheConfig; import org.eclipse.jgit.util.FS; @@ -113,13 +122,8 @@ public abstract class LocalDiskRepositoryTestCase { ceilTestDirectories(getCeilings()); SystemReader.setInstance(mockSystemReader); - final long now = mockSystemReader.getCurrentTime(); - final int tz = mockSystemReader.getTimezone(now); author = new PersonIdent("J. Author", "jauthor@example.com"); - author = new PersonIdent(author, now, tz); - committer = new PersonIdent("J. Committer", "jcommitter@example.com"); - committer = new PersonIdent(committer, now, tz); final WindowCacheConfig c = new WindowCacheConfig(); c.setPackedGitLimit(128 * WindowCacheConfig.KB); 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 28a95569e8..6faa2ece48 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 @@ -50,10 +50,12 @@ import java.io.IOException; import java.lang.reflect.Field; import java.text.DateFormat; import java.text.SimpleDateFormat; +import java.time.Duration; import java.util.HashMap; import java.util.Locale; import java.util.Map; import java.util.TimeZone; +import java.util.concurrent.TimeUnit; import org.eclipse.jgit.errors.ConfigInvalidException; import org.eclipse.jgit.lib.Config; @@ -61,6 +63,8 @@ import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.storage.file.FileBasedConfig; import org.eclipse.jgit.util.FS; import org.eclipse.jgit.util.SystemReader; +import org.eclipse.jgit.util.time.MonotonicClock; +import org.eclipse.jgit.util.time.ProposedTimestamp; /** * Mock {@link SystemReader} for tests. @@ -146,6 +150,27 @@ public class MockSystemReader extends SystemReader { return now; } + @Override + public MonotonicClock getClock() { + return new MonotonicClock() { + @Override + public ProposedTimestamp propose() { + long t = getCurrentTime(); + return new ProposedTimestamp() { + @Override + public long read(TimeUnit unit) { + return unit.convert(t, TimeUnit.MILLISECONDS); + } + + @Override + public void blockUntil(Duration maxWait) { + // Do not wait. + } + }; + } + }; + } + /** * Adjusts the current time in seconds. * 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 0a2345f088..a44e999378 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 @@ -46,6 +46,7 @@ package org.eclipse.jgit.junit; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; +import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; @@ -103,7 +104,6 @@ import org.eclipse.jgit.treewalk.TreeWalk; import org.eclipse.jgit.treewalk.filter.PathFilterGroup; import org.eclipse.jgit.util.ChangeIdUtil; import org.eclipse.jgit.util.FileUtils; -import org.eclipse.jgit.util.io.SafeBufferedOutputStream; /** * Wrapper to make creating test data easier. @@ -885,14 +885,14 @@ public class TestRepository<R extends Repository> { pack = nameFor(odb, name, ".pack"); try (OutputStream out = - new SafeBufferedOutputStream(new FileOutputStream(pack))) { + new BufferedOutputStream(new FileOutputStream(pack))) { pw.writePack(m, m, out); } pack.setReadOnly(); idx = nameFor(odb, name, ".idx"); try (OutputStream out = - new SafeBufferedOutputStream(new FileOutputStream(idx))) { + new BufferedOutputStream(new FileOutputStream(idx))) { pw.writeIndex(out); } idx.setReadOnly(); diff --git a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/time/MonotonicFakeClock.java b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/time/MonotonicFakeClock.java new file mode 100644 index 0000000000..f09d303d55 --- /dev/null +++ b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/time/MonotonicFakeClock.java @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2016, 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.junit.time; + +import java.time.Duration; +import java.util.concurrent.TimeUnit; + +import org.eclipse.jgit.util.time.MonotonicClock; +import org.eclipse.jgit.util.time.ProposedTimestamp; + +/** + * Fake {@link MonotonicClock} for testing code that uses Clock. + * + * @since 4.6 + */ +public class MonotonicFakeClock implements MonotonicClock { + private long now = TimeUnit.SECONDS.toMicros(42); + + /** + * Advance the time returned by future calls to {@link #propose()}. + * + * @param add + * amount of time to add; must be {@code > 0}. + * @param unit + * unit of {@code add}. + */ + public void tick(long add, TimeUnit unit) { + if (add <= 0) { + throw new IllegalArgumentException(); + } + now += unit.toMillis(add); + } + + @Override + public ProposedTimestamp propose() { + long t = now++; + return new ProposedTimestamp() { + @Override + public long read(TimeUnit unit) { + return unit.convert(t, TimeUnit.MILLISECONDS); + } + + @Override + public void blockUntil(Duration maxWait) { + // Nothing to do, since fake time does not go backwards. + } + }; + } +} diff --git a/org.eclipse.jgit.lfs.server.test/.classpath b/org.eclipse.jgit.lfs.server.test/.classpath index 2fdcc94f18..4f9f6bf22f 100644 --- a/org.eclipse.jgit.lfs.server.test/.classpath +++ b/org.eclipse.jgit.lfs.server.test/.classpath @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <classpath> - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> <classpathentry kind="src" path="tst"/> <classpathentry kind="output" path="bin"/> 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 87210fb160..10c29d5576 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 @@ -7,9 +7,9 @@ org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nul org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.7 +org.eclipse.jdt.core.compiler.compliance=1.8 org.eclipse.jdt.core.compiler.debug.lineNumber=generate org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.debug.sourceFile=generate @@ -112,7 +112,7 @@ org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=error -org.eclipse.jdt.core.compiler.source=1.7 +org.eclipse.jdt.core.compiler.source=1.8 org.eclipse.jdt.core.formatter.align_type_members_on_columns=false org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 diff --git a/org.eclipse.jgit.lfs.server.test/BUCK b/org.eclipse.jgit.lfs.server.test/BUCK index 9d6e72fcf5..25e9f09c18 100644 --- a/org.eclipse.jgit.lfs.server.test/BUCK +++ b/org.eclipse.jgit.lfs.server.test/BUCK @@ -30,6 +30,5 @@ for t in TESTS: '//lib:servlet-api', '//lib:commons-logging', ], - source_under_test = ['//org.eclipse.jgit.lfs.server:jgit-lfs-server'], vm_args = ['-Xmx256m', '-Dfile.encoding=UTF-8'], ) 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 2513eb26ea..405e07a725 100644 --- a/org.eclipse.jgit.lfs.server.test/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.lfs.server.test/META-INF/MANIFEST.MF @@ -2,10 +2,10 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Bundle-SymbolicName: org.eclipse.jgit.lfs.server.test -Bundle-Version: 4.5.3.qualifier +Bundle-Version: 4.6.2.qualifier Bundle-Vendor: %provider_name Bundle-Localization: plugin -Bundle-RequiredExecutionEnvironment: JavaSE-1.7 +Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Import-Package: javax.servlet;version="[3.1.0,4.0.0)", javax.servlet.http;version="[3.1.0,4.0.0)", org.apache.http;version="[4.3.0,5.0.0)", @@ -13,25 +13,25 @@ Import-Package: javax.servlet;version="[3.1.0,4.0.0)", org.apache.http.client.methods;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.eclipse.jetty.continuation;version="[9.0.0,10.0.0)", - org.eclipse.jetty.http;version="[9.0.0,10.0.0)", - org.eclipse.jetty.io;version="[9.0.0,10.0.0)", - org.eclipse.jetty.security;version="[9.0.0,10.0.0)", - org.eclipse.jetty.security.authentication;version="[9.0.0,10.0.0)", - org.eclipse.jetty.server;version="[9.0.0,10.0.0)", - org.eclipse.jetty.server.handler;version="[9.0.0,10.0.0)", - org.eclipse.jetty.server.nio;version="[9.0.0,10.0.0)", - org.eclipse.jetty.servlet;version="[9.0.0,10.0.0)", - org.eclipse.jetty.util;version="[9.0.0,10.0.0)", - org.eclipse.jetty.util.component;version="[9.0.0,10.0.0)", - org.eclipse.jetty.util.log;version="[9.0.0,10.0.0)", - org.eclipse.jetty.util.security;version="[9.0.0,10.0.0)", - org.eclipse.jetty.util.thread;version="[9.0.0,10.0.0)", - org.eclipse.jgit.junit.http;version="[4.5.3,4.6.0)", - org.eclipse.jgit.lfs.lib;version="[4.5.3,4.6.0)", - org.eclipse.jgit.lfs.server.fs;version="[4.5.3,4.6.0)", - org.eclipse.jgit.lfs.test;version="[4.5.3,4.6.0)", - org.eclipse.jgit.util;version="[4.5.3,4.6.0)", + org.eclipse.jetty.continuation;version="[9.0.0,9.4.0)", + org.eclipse.jetty.http;version="[9.0.0,9.4.0)", + org.eclipse.jetty.io;version="[9.0.0,9.4.0)", + org.eclipse.jetty.security;version="[9.0.0,9.4.0)", + org.eclipse.jetty.security.authentication;version="[9.0.0,9.4.0)", + org.eclipse.jetty.server;version="[9.0.0,9.4.0)", + org.eclipse.jetty.server.handler;version="[9.0.0,9.4.0)", + org.eclipse.jetty.server.nio;version="[9.0.0,9.4.0)", + org.eclipse.jetty.servlet;version="[9.0.0,9.4.0)", + org.eclipse.jetty.util;version="[9.0.0,9.4.0)", + 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.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.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 bcfbd37f5c..d178feff68 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.5.3-SNAPSHOT</version> + <version>4.6.2-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.lfs.server.test</artifactId> diff --git a/org.eclipse.jgit.lfs.server.test/tst/org/eclipse/jgit/lfs/server/fs/LfsServerTest.java b/org.eclipse.jgit.lfs.server.test/tst/org/eclipse/jgit/lfs/server/fs/LfsServerTest.java index 4d948b960f..e10660dd57 100644 --- a/org.eclipse.jgit.lfs.server.test/tst/org/eclipse/jgit/lfs/server/fs/LfsServerTest.java +++ b/org.eclipse.jgit.lfs.server.test/tst/org/eclipse/jgit/lfs/server/fs/LfsServerTest.java @@ -84,7 +84,6 @@ import org.eclipse.jgit.util.IO; import org.junit.After; import org.junit.Before; -@SuppressWarnings("restriction") public abstract class LfsServerTest { private static final long timeout = /* 10 sec */ 10 * 1000; diff --git a/org.eclipse.jgit.lfs.server/.classpath b/org.eclipse.jgit.lfs.server/.classpath index 04a2be7bdb..cfcf24a51e 100644 --- a/org.eclipse.jgit.lfs.server/.classpath +++ b/org.eclipse.jgit.lfs.server/.classpath @@ -2,7 +2,7 @@ <classpath> <classpathentry kind="src" path="src"/> <classpathentry kind="src" path="resources"/> - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> <classpathentry kind="output" path="bin"/> </classpath> 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 1ce7cd0219..808ec3a2c6 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 @@ -7,9 +7,9 @@ org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nul org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.7 +org.eclipse.jdt.core.compiler.compliance=1.8 org.eclipse.jdt.core.compiler.debug.lineNumber=generate org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.debug.sourceFile=generate @@ -112,7 +112,7 @@ org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=error -org.eclipse.jdt.core.compiler.source=1.7 +org.eclipse.jdt.core.compiler.source=1.8 org.eclipse.jdt.core.formatter.align_type_members_on_columns=false org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 diff --git a/org.eclipse.jgit.lfs.server/META-INF/MANIFEST.MF b/org.eclipse.jgit.lfs.server/META-INF/MANIFEST.MF index 8090f15d6f..3e8a9d17cd 100644 --- a/org.eclipse.jgit.lfs.server/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.lfs.server/META-INF/MANIFEST.MF @@ -2,34 +2,35 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Bundle-SymbolicName: org.eclipse.jgit.lfs.server -Bundle-Version: 4.5.3.qualifier +Bundle-Version: 4.6.2.qualifier Bundle-Localization: plugin Bundle-Vendor: %provider_name -Export-Package: org.eclipse.jgit.lfs.server;version="4.5.3"; +Export-Package: org.eclipse.jgit.lfs.server;version="4.6.2"; uses:="javax.servlet.http, org.eclipse.jgit.lfs.lib", - org.eclipse.jgit.lfs.server.fs;version="4.5.3"; + org.eclipse.jgit.lfs.server.fs;version="4.6.2"; uses:="javax.servlet, javax.servlet.http, org.eclipse.jgit.lfs.server, org.eclipse.jgit.lfs.lib", - org.eclipse.jgit.lfs.server.internal;version="4.5.3";x-internal:=true, - org.eclipse.jgit.lfs.server.s3;version="4.5.3"; + org.eclipse.jgit.lfs.server.internal;version="4.6.2";x-internal:=true, + org.eclipse.jgit.lfs.server.s3;version="4.6.2"; uses:="org.eclipse.jgit.lfs.server, org.eclipse.jgit.lfs.lib" -Bundle-RequiredExecutionEnvironment: JavaSE-1.7 +Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Import-Package: com.google.gson;version="[2.2.4,3.0.0)", javax.servlet;version="[3.1.0,4.0.0)", javax.servlet.annotation;version="[3.1.0,4.0.0)", 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.5.3,4.6.0)", - org.eclipse.jgit.internal;version="[4.5.3,4.6.0)", - org.eclipse.jgit.internal.storage.file;version="[4.5.3,4.6.0)", - org.eclipse.jgit.lfs.errors;version="[4.5.3,4.6.0)", - org.eclipse.jgit.lfs.lib;version="[4.5.3,4.6.0)", - org.eclipse.jgit.nls;version="[4.5.3,4.6.0)", - org.eclipse.jgit.transport.http;version="[4.5.3,4.6.0)", - org.eclipse.jgit.transport.http.apache;version="[4.5.3,4.6.0)", - org.eclipse.jgit.util;version="[4.5.3,4.6.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)" diff --git a/org.eclipse.jgit.lfs.server/pom.xml b/org.eclipse.jgit.lfs.server/pom.xml index 935767b1bf..cc84686810 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.5.3-SNAPSHOT</version> + <version>4.6.2-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.lfs.server</artifactId> diff --git a/org.eclipse.jgit.lfs.server/resources/org/eclipse/jgit/lfs/server/internal/LfsServerText.properties b/org.eclipse.jgit.lfs.server/resources/org/eclipse/jgit/lfs/server/internal/LfsServerText.properties index f97acacccc..b2b487eefc 100644 --- a/org.eclipse.jgit.lfs.server/resources/org/eclipse/jgit/lfs/server/internal/LfsServerText.properties +++ b/org.eclipse.jgit.lfs.server/resources/org/eclipse/jgit/lfs/server/internal/LfsServerText.properties @@ -1,4 +1,3 @@ -corruptLongObject=The content hash ''{0}'' of the long object ''{1}'' doesn''t match its id, the corrupt object will be deleted. failedToCalcSignature=Failed to calculate a request signature: {0} invalidPathInfo=Invalid pathInfo ''{0}'' does not match ''/'{'SHA-256'}''' objectNotFound=Object ''{0}'' not found 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 eb49ff0939..841074beeb 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 @@ -44,8 +44,8 @@ package org.eclipse.jgit.lfs.server; import static java.nio.charset.StandardCharsets.UTF_8; import static org.apache.http.HttpStatus.SC_FORBIDDEN; -import static org.apache.http.HttpStatus.SC_INTERNAL_SERVER_ERROR; import static org.apache.http.HttpStatus.SC_INSUFFICIENT_STORAGE; +import static org.apache.http.HttpStatus.SC_INTERNAL_SERVER_ERROR; 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; diff --git a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/FileLfsRepository.java b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/FileLfsRepository.java index dd70a364e4..a05fa01424 100644 --- a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/FileLfsRepository.java +++ b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/FileLfsRepository.java @@ -53,6 +53,7 @@ import java.nio.file.StandardOpenOption; import java.util.Collections; import org.eclipse.jgit.annotations.Nullable; +import org.eclipse.jgit.lfs.internal.AtomicObjectOutputStream; import org.eclipse.jgit.lfs.lib.AnyLongObjectId; import org.eclipse.jgit.lfs.lib.Constants; import org.eclipse.jgit.lfs.server.LargeFileRepository; 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 2ecba6d029..a8e3c11e27 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 @@ -125,7 +125,20 @@ public class FileLfsServlet extends HttpServlet { } } - private AnyLongObjectId getObjectToTransfer(HttpServletRequest req, + /** + * Retrieve object id from request + * + * @param req + * servlet request + * @param rsp + * servlet response + * @return object id, or <code>null</code> if the object id could not be + * retrieved + * @throws IOException + * if an I/O error occurs + * @since 4.6 + */ + protected AnyLongObjectId getObjectToTransfer(HttpServletRequest req, HttpServletResponse rsp) throws IOException { String info = req.getPathInfo(); int length = 1 + Constants.LONG_OBJECT_ID_STRING_LENGTH; @@ -174,7 +187,20 @@ public class FileLfsServlet extends HttpServlet { } } - static void sendError(HttpServletResponse rsp, int status, String message) + /** + * Send an error response. + * + * @param rsp + * the servlet response + * @param status + * HTTP status code + * @param message + * error message + * @throws IOException + * on failure to send the response + * @since 4.6 + */ + protected static void sendError(HttpServletResponse rsp, int status, String message) throws IOException { rsp.setStatus(status); PrintWriter writer = rsp.getWriter(); 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 d44b3db5de..84e4e6f1c6 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 @@ -59,13 +59,16 @@ import javax.servlet.http.HttpServletResponse; import org.apache.http.HttpStatus; import org.eclipse.jgit.lfs.errors.CorruptLongObjectException; +import org.eclipse.jgit.lfs.internal.AtomicObjectOutputStream; import org.eclipse.jgit.lfs.lib.AnyLongObjectId; import org.eclipse.jgit.lfs.lib.Constants; /** - * Handle asynchronous object upload + * Handle asynchronous object upload. + * + * @since 4.6 */ -class ObjectUploadListener implements ReadListener { +public class ObjectUploadListener implements ReadListener { private static Logger LOG = Logger .getLogger(ObjectUploadListener.class.getName()); @@ -138,6 +141,9 @@ class ObjectUploadListener implements ReadListener { close(); } + /** + * @throws IOException + */ protected void close() throws IOException { try { inChannel.close(); @@ -173,4 +179,4 @@ class ObjectUploadListener implements ReadListener { LOG.log(Level.SEVERE, ex.getMessage(), ex); } } -}
\ No newline at end of file +} diff --git a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/internal/LfsServerText.java b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/internal/LfsServerText.java index c5ad53a541..2e088fde8d 100644 --- a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/internal/LfsServerText.java +++ b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/internal/LfsServerText.java @@ -58,7 +58,6 @@ public class LfsServerText extends TranslationBundle { } // @formatter:off - /***/ public String corruptLongObject; /***/ public String failedToCalcSignature; /***/ public String invalidPathInfo; /***/ public String objectNotFound; diff --git a/org.eclipse.jgit.lfs.test/.classpath b/org.eclipse.jgit.lfs.test/.classpath index efc781df01..e43ae76c50 100644 --- a/org.eclipse.jgit.lfs.test/.classpath +++ b/org.eclipse.jgit.lfs.test/.classpath @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <classpath> - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> <classpathentry kind="src" path="src"/> <classpathentry kind="src" path="tst"/> 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 87210fb160..10c29d5576 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 @@ -7,9 +7,9 @@ org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nul org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.7 +org.eclipse.jdt.core.compiler.compliance=1.8 org.eclipse.jdt.core.compiler.debug.lineNumber=generate org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.debug.sourceFile=generate @@ -112,7 +112,7 @@ org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=error -org.eclipse.jdt.core.compiler.source=1.7 +org.eclipse.jdt.core.compiler.source=1.8 org.eclipse.jdt.core.formatter.align_type_members_on_columns=false org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 diff --git a/org.eclipse.jgit.lfs.test/BUCK b/org.eclipse.jgit.lfs.test/BUCK index d0fb96f9cd..1298e166c0 100644 --- a/org.eclipse.jgit.lfs.test/BUCK +++ b/org.eclipse.jgit.lfs.test/BUCK @@ -15,7 +15,6 @@ for t in TESTS: '//lib:hamcrest-library', '//lib:junit', ], - source_under_test = ['//org.eclipse.jgit.lfs:jgit-lfs'], ) java_library( diff --git a/org.eclipse.jgit.lfs.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.lfs.test/META-INF/MANIFEST.MF index 933002aa9b..e859f6337a 100644 --- a/org.eclipse.jgit.lfs.test/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.lfs.test/META-INF/MANIFEST.MF @@ -2,18 +2,19 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Bundle-SymbolicName: org.eclipse.jgit.lfs.test -Bundle-Version: 4.5.3.qualifier +Bundle-Version: 4.6.2.qualifier Bundle-Vendor: %provider_name Bundle-Localization: plugin -Bundle-RequiredExecutionEnvironment: JavaSE-1.7 -Import-Package: org.eclipse.jgit.junit;version="[4.5.3,4.6.0)", - org.eclipse.jgit.lfs.errors;version="[4.5.3,4.6.0)", - org.eclipse.jgit.lfs.lib;version="[4.5.3,4.6.0)", - org.eclipse.jgit.lib;version="[4.5.3,4.6.0)", - org.eclipse.jgit.util;version="[4.5.3,4.6.0)", +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)", 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.5.3";x-friends:="org.eclipse.jgit.lfs.server.test" +Export-Package: org.eclipse.jgit.lfs.test;version="4.6.2";x-friends:="org.eclipse.jgit.lfs.server.test" diff --git a/org.eclipse.jgit.lfs.test/pom.xml b/org.eclipse.jgit.lfs.test/pom.xml index 77d8d0edcd..a06aefc1f8 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.5.3-SNAPSHOT</version> + <version>4.6.2-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.lfs.test</artifactId> diff --git a/org.eclipse.jgit.lfs.test/tst/org/eclipse/jgit/lfs/lib/LFSPointerTest.java b/org.eclipse.jgit.lfs.test/tst/org/eclipse/jgit/lfs/lib/LFSPointerTest.java new file mode 100644 index 0000000000..4827d3d113 --- /dev/null +++ b/org.eclipse.jgit.lfs.test/tst/org/eclipse/jgit/lfs/lib/LFSPointerTest.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2016, Christian Halstrick <christian.halstrick@sap.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.lib; + +import static org.junit.Assert.assertEquals; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; + +import org.eclipse.jgit.lfs.LfsPointer; +import org.junit.Test; + +/* + * Test LfsPointer file abstraction + */ +public class LFSPointerTest { + @Test + public void testEncoding() throws IOException { + final String s = "27e15b72937fc8f558da24ac3d50ec20302a4cf21e33b87ae8e4ce90e89c4b10"; + AnyLongObjectId id = LongObjectId.fromString(s); + LfsPointer ptr = new LfsPointer(id, 4); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ptr.encode(baos); + baos.close(); + assertEquals("version https://git-lfs.github.com/spec/v1\noid sha256:" + + s + "\nsize 4\n", + baos.toString(StandardCharsets.UTF_8.name())); + } +} diff --git a/org.eclipse.jgit.lfs/.classpath b/org.eclipse.jgit.lfs/.classpath index 04a2be7bdb..cfcf24a51e 100644 --- a/org.eclipse.jgit.lfs/.classpath +++ b/org.eclipse.jgit.lfs/.classpath @@ -2,7 +2,7 @@ <classpath> <classpathentry kind="src" path="src"/> <classpathentry kind="src" path="resources"/> - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> <classpathentry kind="output" path="bin"/> </classpath> diff --git a/org.eclipse.jgit.lfs/.settings/.api_filters b/org.eclipse.jgit.lfs/.settings/.api_filters new file mode 100644 index 0000000000..be675b1ee1 --- /dev/null +++ b/org.eclipse.jgit.lfs/.settings/.api_filters @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<component id="org.eclipse.jgit.lfs" version="2"> + <resource path="src/org/eclipse/jgit/lfs/lib/Constants.java" type="org.eclipse.jgit.lfs.lib.Constants"> + <filter id="388100214"> + <message_arguments> + <message_argument value="org.eclipse.jgit.lfs.lib.Constants"/> + <message_argument value="CONTENT_TYPE_GIT_LFS_JSON"/> + </message_arguments> + </filter> + <filter id="388100214"> + <message_arguments> + <message_argument value="org.eclipse.jgit.lfs.lib.Constants"/> + <message_argument value="HDR_APPLICATION_OCTET_STREAM"/> + </message_arguments> + </filter> + </resource> +</component> diff --git a/org.eclipse.jgit.lfs/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jgit.lfs/.settings/org.eclipse.jdt.core.prefs index 1ce7cd0219..808ec3a2c6 100644 --- a/org.eclipse.jgit.lfs/.settings/org.eclipse.jdt.core.prefs +++ b/org.eclipse.jgit.lfs/.settings/org.eclipse.jdt.core.prefs @@ -7,9 +7,9 @@ org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nul org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.7 +org.eclipse.jdt.core.compiler.compliance=1.8 org.eclipse.jdt.core.compiler.debug.lineNumber=generate org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.debug.sourceFile=generate @@ -112,7 +112,7 @@ org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=error -org.eclipse.jdt.core.compiler.source=1.7 +org.eclipse.jdt.core.compiler.source=1.8 org.eclipse.jdt.core.formatter.align_type_members_on_columns=false org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 diff --git a/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF b/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF index 854ca1d0d8..d5d1f7cbdd 100644 --- a/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF @@ -2,14 +2,17 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Bundle-SymbolicName: org.eclipse.jgit.lfs -Bundle-Version: 4.5.3.qualifier +Bundle-Version: 4.6.2.qualifier Bundle-Localization: plugin Bundle-Vendor: %provider_name -Export-Package: org.eclipse.jgit.lfs.errors;version="4.5.3", - org.eclipse.jgit.lfs.internal;version="4.5.3";x-friends:="org.eclipse.jgit.lfs.test", - org.eclipse.jgit.lfs.lib;version="4.5.3" -Bundle-RequiredExecutionEnvironment: JavaSE-1.7 -Import-Package: org.eclipse.jgit.internal.storage.file;version="[4.5.3,4.6.0)", - org.eclipse.jgit.lib;version="[4.5.3,4.6.0)", - org.eclipse.jgit.nls;version="[4.5.3,4.6.0)", - org.eclipse.jgit.util;version="[4.5.3,4.6.0)" +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" +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)" diff --git a/org.eclipse.jgit.lfs/pom.xml b/org.eclipse.jgit.lfs/pom.xml index 179479e7d2..049b3601a7 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.5.3-SNAPSHOT</version> + <version>4.6.2-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 7c3aea2261..5e52a782f0 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 @@ -1,7 +1,9 @@ +corruptLongObject=The content hash ''{0}'' of the long object ''{1}'' doesn''t match its id, the corrupt object will be deleted. incorrectLONG_OBJECT_ID_LENGTH=Incorrect LONG_OBJECT_ID_LENGTH. +inconsistentMediafileLength=mediafile {0} has unexpected length; expected {1} but found {2}. invalidLongId=Invalid id: {0} invalidLongIdLength=Invalid id length {0}; should be {1} requiredHashFunctionNotAvailable=Required hash function {0} not available. repositoryNotFound=Repository {0} not found repositoryReadOnly=Repository {0} is read-only -lfsUnavailable=LFS is not available for repository {0}
\ No newline at end of file +lfsUnavailable=LFS is not available for 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 new file mode 100644 index 0000000000..66feca7518 --- /dev/null +++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/CleanFilter.java @@ -0,0 +1,171 @@ +/* + * Copyright (C) 2016, Christian Halstrick <christian.halstrick@sap.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; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; + +import org.eclipse.jgit.attributes.FilterCommand; +import org.eclipse.jgit.attributes.FilterCommandFactory; +import org.eclipse.jgit.attributes.FilterCommandRegistry; +import org.eclipse.jgit.lfs.errors.CorruptMediaFile; +import org.eclipse.jgit.lfs.internal.AtomicObjectOutputStream; +import org.eclipse.jgit.lfs.lib.AnyLongObjectId; +import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.util.FileUtils; + +/** + * Built-in LFS clean filter + * + * When new content is about to be added to the git repository and this filter + * is configured for that content, then this filter will replace the original + * content with content of a so-called LFS pointer file. The pointer file + * content will then be added to the git repository. Additionally this filter + * writes the original content in a so-called 'media file' to '.git/lfs/objects/ + * <first-two-characters-of-contentid>/<rest-of-contentid>' + * + * @see <a href="https://github.com/github/git-lfs/blob/master/docs/spec.md">Git + * LFS Specification</a> + * @since 4.6 + */ +public class CleanFilter extends FilterCommand { + /** + * The factory is responsible for creating instances of {@link CleanFilter} + */ + public final static FilterCommandFactory FACTORY = new FilterCommandFactory() { + + @Override + public FilterCommand create(Repository db, InputStream in, + OutputStream out) throws IOException { + return new CleanFilter(db, in, out); + } + }; + + /** + * Registers this filter by calling + * {@link FilterCommandRegistry#register(String, FilterCommandFactory)} + */ + public final static void register() { + FilterCommandRegistry.register( + org.eclipse.jgit.lib.Constants.BUILTIN_FILTER_PREFIX + + "lfs/clean", //$NON-NLS-1$ + FACTORY); + } + + // Used to compute the hash for the original content + private AtomicObjectOutputStream aOut; + + private Lfs lfsUtil; + + // the size of the original content + private long size; + + // a temporary file into which the original content is written. When no + // errors occur this file will be renamed to the mediafile + private Path tmpFile; + + /** + * @param db + * the repository + * @param in + * an {@link InputStream} providing the original content + * @param out + * the {@link OutputStream} into which the content of the pointer + * file should be written. That's the content which will be added + * to the git repository + * @throws IOException + * when the creation of the temporary file fails or when no + * {@link OutputStream} for this file can be created + */ + public CleanFilter(Repository db, InputStream in, OutputStream out) + throws IOException { + super(in, out); + lfsUtil = new Lfs(db.getDirectory().toPath().resolve("lfs")); //$NON-NLS-1$ + Files.createDirectories(lfsUtil.getLfsTmpDir()); + tmpFile = lfsUtil.createTmpFile(); + this.aOut = new AtomicObjectOutputStream(tmpFile.toAbsolutePath()); + } + + public int run() throws IOException { + try { + byte[] buf = new byte[8192]; + int length = in.read(buf); + if (length != -1) { + aOut.write(buf, 0, length); + size += length; + return length; + } else { + aOut.close(); + AnyLongObjectId loid = aOut.getId(); + aOut = null; + Path mediaFile = lfsUtil.getMediaFile(loid); + if (Files.isRegularFile(mediaFile)) { + long fsSize = Files.size(mediaFile); + if (fsSize != size) { + throw new CorruptMediaFile(mediaFile, size, fsSize); + } else { + FileUtils.delete(tmpFile.toFile()); + } + } else { + FileUtils.mkdirs(mediaFile.getParent().toFile(), true); + FileUtils.rename(tmpFile.toFile(), mediaFile.toFile(), + StandardCopyOption.ATOMIC_MOVE); + } + LfsPointer lfsPointer = new LfsPointer(loid, size); + lfsPointer.encode(out); + out.close(); + return -1; + } + } catch (IOException e) { + if (aOut != null) { + aOut.abort(); + } + out.close(); + throw e; + } + } +} diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/Lfs.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/Lfs.java new file mode 100644 index 0000000000..75e34e0f63 --- /dev/null +++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/Lfs.java @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2016, Christian Halstrick <christian.halstrick@sap.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; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; + +import org.eclipse.jgit.lfs.lib.AnyLongObjectId; + +/** + * Class which represents the lfs folder hierarchy inside a .git folder + * + * @since 4.6 + */ +public class Lfs { + private Path root; + + private Path objDir; + + private Path tmpDir; + + /** + * @param root + * the path to the LFS media directory. Will be "<repo>/.git/lfs" + */ + public Lfs(Path root) { + this.root = root; + } + + /** + * @return the path to the LFS directory + */ + public Path getLfsRoot() { + return root; + } + + /** + * @return the path to the temp directory used by LFS. Will be + * "<repo>/.git/lfs/tmp" + */ + public Path getLfsTmpDir() { + if (tmpDir == null) { + tmpDir = root.resolve("tmp"); //$NON-NLS-1$ + } + return tmpDir; + } + + /** + * @return the path to the object directory used by LFS. Will be + * "<repo>/.git/lfs/objects" + */ + public Path getLfsObjDir() { + if (objDir == null) { + objDir = root.resolve("objects"); //$NON-NLS-1$ + } + return objDir; + } + + /** + * @param id + * the id of the mediafile + * @return the file which stores the original content. This will be files + * underneath + * "<repo>/.git/lfs/objects/<firstTwoLettersOfID>/<remainingLettersOfID>" + */ + public Path getMediaFile(AnyLongObjectId id) { + String idStr = id.name(); + return getLfsObjDir().resolve(idStr.substring(0, 2)) + .resolve(idStr.substring(2)); + } + + /** + * Create a new temp file in the LFS directory + * + * @return a new temporary file in the LFS directory + * @throws IOException + * when the temp file could not be created + */ + public Path createTmpFile() throws IOException { + return Files.createTempFile(getLfsTmpDir(), null, null); + } + +} 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 new file mode 100644 index 0000000000..bbea53567f --- /dev/null +++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/LfsPointer.java @@ -0,0 +1,176 @@ +/* + * Copyright (C) 2016, Christian Halstrick <christian.halstrick@sap.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; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.PrintStream; +import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; +import java.nio.charset.UnsupportedCharsetException; + +import org.eclipse.jgit.annotations.Nullable; +import org.eclipse.jgit.lfs.lib.AnyLongObjectId; +import org.eclipse.jgit.lfs.lib.Constants; +import org.eclipse.jgit.lfs.lib.LongObjectId; + +/** + * Represents an LFS pointer file + * + * @since 4.6 + */ +public class LfsPointer { + /** + * The version of the LfsPointer file format + */ + public static final String VERSION = "https://git-lfs.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$ + + private AnyLongObjectId oid; + + private long size; + + /** + * @param oid + * the id of the content + * @param size + * the size of the content + */ + public LfsPointer(AnyLongObjectId oid, long size) { + this.oid = oid; + this.size = size; + } + + /** + * @return the id of the content + */ + public AnyLongObjectId getOid() { + return oid; + } + + /** + * @return the size of the content + */ + public long getSize() { + return size; + } + + /** + * Encode this object into the LFS format defined by {@link #VERSION} + * + * @param out + * the {@link OutputStream} into which the encoded data should be + * written + */ + public void encode(OutputStream out) { + try (PrintStream ps = new PrintStream(out, false, + StandardCharsets.UTF_8.name())) { + ps.print("version "); //$NON-NLS-1$ + ps.print(VERSION + "\n"); //$NON-NLS-1$ + ps.print("oid " + HASH_FUNCTION_NAME + ":"); //$NON-NLS-1$ //$NON-NLS-2$ + ps.print(oid.name() + "\n"); //$NON-NLS-1$ + ps.print("size "); //$NON-NLS-1$ + ps.print(size + "\n"); //$NON-NLS-1$ + } catch (UnsupportedEncodingException e) { + // should not happen, we are using a standard charset + throw new UnsupportedCharsetException( + StandardCharsets.UTF_8.name()); + } + } + + /** + * Try to parse the data provided by an InputStream to the format defined by + * {@link #VERSION} + * + * @param in + * the {@link InputStream} from where to read the data + * @return an {@link LfsPointer} or <code>null</code> if the stream was not + * parseable as LfsPointer + * @throws IOException + */ + @Nullable + public static LfsPointer parseLfsPointer(InputStream in) + throws IOException { + boolean versionLine = false; + LongObjectId id = null; + long sz = -1; + + try (BufferedReader br = new BufferedReader( + new InputStreamReader(in, StandardCharsets.UTF_8.name()))) { + for (String s = br.readLine(); s != null; s = br.readLine()) { + 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)) { + 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) { + return new LfsPointer(id, sz); + } + } + return null; + } + + @Override + public String toString() { + return "LfsPointer: oid=" + oid.name() + ", size=" //$NON-NLS-1$ //$NON-NLS-2$ + + size; + } +} + diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/SmudgeFilter.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/SmudgeFilter.java new file mode 100644 index 0000000000..233247779d --- /dev/null +++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/SmudgeFilter.java @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2016, Christian Halstrick <christian.halstrick@sap.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; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.file.Files; +import java.nio.file.Path; + +import org.eclipse.jgit.attributes.FilterCommand; +import org.eclipse.jgit.attributes.FilterCommandFactory; +import org.eclipse.jgit.attributes.FilterCommandRegistry; +import org.eclipse.jgit.lfs.lib.Constants; +import org.eclipse.jgit.lib.Repository; + +/** + * Built-in LFS smudge filter + * + * When content is read from git's object-database and written to the filesystem + * and this filter is configured for that content, then this filter will replace + * the content of LFS pointer files with the original content. This happens e.g. + * when a checkout needs to update a working tree file which is under LFS + * control. This implementation expects that the origin content is already + * available in the .git/lfs/objects folder. This implementation will not + * contact any LFS servers in order to get the missing content. + * + * @since 4.6 + */ +public class SmudgeFilter extends FilterCommand { + /** + * The factory is responsible for creating instances of {@link SmudgeFilter} + */ + public final static FilterCommandFactory FACTORY = new FilterCommandFactory() { + @Override + public FilterCommand create(Repository db, InputStream in, + OutputStream out) throws IOException { + return new SmudgeFilter(db, in, out); + } + }; + + /** + * Registers this filter in JGit by calling + */ + public final static void register() { + FilterCommandRegistry.register( + org.eclipse.jgit.lib.Constants.BUILTIN_FILTER_PREFIX + + "lfs/smudge", //$NON-NLS-1$ + FACTORY); + } + + private Lfs lfs; + + /** + * @param db + * @param in + * @param out + * @throws IOException + */ + public SmudgeFilter(Repository db, InputStream in, OutputStream out) + throws IOException { + super(in, out); + lfs = new Lfs(db.getDirectory().toPath().resolve(Constants.LFS)); + LfsPointer res = LfsPointer.parseLfsPointer(in); + if (res != null) { + Path mediaFile = lfs.getMediaFile(res.getOid()); + if (Files.exists(mediaFile)) { + this.in = Files.newInputStream(mediaFile); + } + } + } + + @Override + public int run() throws IOException { + int b; + if (in != null) { + while ((b = in.read()) != -1) { + out.write(b); + } + in.close(); + } + out.close(); + return -1; + } +} diff --git a/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/errors/CorruptMediaFile.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/errors/CorruptMediaFile.java new file mode 100644 index 0000000000..f2b51c0442 --- /dev/null +++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/errors/CorruptMediaFile.java @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2016, Christian Halstrick <christian.halstrick@sap.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.io.IOException; +import java.nio.file.Path; +import java.text.MessageFormat; + +import org.eclipse.jgit.lfs.internal.LfsText; + +/** + * Thrown when a LFS mediafile is found which doesn't have the expected size + * + * @since 4.6 + */ +public class CorruptMediaFile extends IOException { + private static final long serialVersionUID = 1L; + + private Path mediaFile; + + private long expectedSize; + + private long size; + + /** + * @param mediaFile + * @param expectedSize + * @param size + */ + @SuppressWarnings("boxing") + public CorruptMediaFile(Path mediaFile, long expectedSize, + long size) { + super(MessageFormat.format(LfsText.get().inconsistentMediafileLength, + mediaFile, expectedSize, size)); + this.mediaFile = mediaFile; + this.expectedSize = expectedSize; + this.size = size; + } + + /** + * @return the media file which seems to be corrupt + */ + public Path getMediaFile() { + return mediaFile; + } + + /** + * @return the expected size of the media file + */ + public long getExpectedSize() { + return expectedSize; + } + + /** + * @return the actual size of the media file in the file system + */ + public long getSize() { + return size; + } +} diff --git a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/AtomicObjectOutputStream.java b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/internal/AtomicObjectOutputStream.java index ecc7c1f36c..867cca5056 100644 --- a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/AtomicObjectOutputStream.java +++ b/org.eclipse.jgit.lfs/src/org/eclipse/jgit/lfs/internal/AtomicObjectOutputStream.java @@ -40,7 +40,7 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package org.eclipse.jgit.lfs.server.fs; +package org.eclipse.jgit.lfs.internal; import java.io.IOException; import java.io.OutputStream; @@ -48,19 +48,19 @@ import java.nio.file.Path; import java.security.DigestOutputStream; import java.text.MessageFormat; +import org.eclipse.jgit.annotations.Nullable; import org.eclipse.jgit.internal.storage.file.LockFile; import org.eclipse.jgit.lfs.errors.CorruptLongObjectException; import org.eclipse.jgit.lfs.lib.AnyLongObjectId; import org.eclipse.jgit.lfs.lib.Constants; import org.eclipse.jgit.lfs.lib.LongObjectId; -import org.eclipse.jgit.lfs.server.internal.LfsServerText; /** * Output stream writing content to a {@link LockFile} which is committed on * close(). The stream checks if the hash of the stream content matches the * id. */ -class AtomicObjectOutputStream extends OutputStream { +public class AtomicObjectOutputStream extends OutputStream { private LockFile locked; @@ -70,7 +70,12 @@ class AtomicObjectOutputStream extends OutputStream { private AnyLongObjectId id; - AtomicObjectOutputStream(Path path, AnyLongObjectId id) + /** + * @param path + * @param id + * @throws IOException + */ + public AtomicObjectOutputStream(Path path, AnyLongObjectId id) throws IOException { locked = new LockFile(path.toFile()); locked.lock(); @@ -79,6 +84,22 @@ class AtomicObjectOutputStream extends OutputStream { Constants.newMessageDigest()); } + /** + * @param path + * @throws IOException + */ + public AtomicObjectOutputStream(Path path) throws IOException { + this(path, null); + } + + /** + * @return content hash of the object which was streamed through this + * stream. May return {@code null} if called before closing this stream. + */ + public @Nullable AnyLongObjectId getId() { + return id; + } + @Override public void write(int b) throws IOException { out.write(b); @@ -98,7 +119,11 @@ class AtomicObjectOutputStream extends OutputStream { public void close() throws IOException { out.close(); if (!aborted) { - verifyHash(); + if (id != null) { + verifyHash(); + } else { + id = LongObjectId.fromRaw(out.getMessageDigest().digest()); + } locked.commit(); } } @@ -109,12 +134,15 @@ class AtomicObjectOutputStream extends OutputStream { if (!contentHash.equals(id)) { abort(); throw new CorruptLongObjectException(id, contentHash, - MessageFormat.format(LfsServerText.get().corruptLongObject, + MessageFormat.format(LfsText.get().corruptLongObject, contentHash, id)); } } - void abort() { + /** + * Aborts the stream. Temporary file will be deleted + */ + public void abort() { locked.unlock(); aborted = true; } 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 365eaa1727..c76df39354 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 @@ -58,6 +58,8 @@ public class LfsText extends TranslationBundle { } // @formatter:off + /***/ public String corruptLongObject; + /***/ public String inconsistentMediafileLength; /***/ public String incorrectLONG_OBJECT_ID_LENGTH; /***/ public String invalidLongId; /***/ public String invalidLongIdLength; 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 d2464126cc..a88057afce 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 @@ -55,8 +55,19 @@ import org.eclipse.jgit.lfs.internal.LfsText; **/ @SuppressWarnings("nls") public final class Constants { - /** Hash function used natively by Git LFS extension for large objects. */ - private static final String LONG_HASH_FUNCTION = "SHA-256"; + /** + * lfs folder + * + * @since 4.6 + */ + public static final String LFS = "lfs"; + + /** + * Hash function used natively by Git LFS extension for large objects. + * + * @since 4.6 + */ + public static final String LONG_HASH_FUNCTION = "SHA-256"; /** * A Git LFS large object hash is 256 bits, i.e. 32 bytes. @@ -104,11 +115,11 @@ public final class Constants { * Content type used by LFS REST API as defined in * {@link "https://github.com/github/git-lfs/blob/master/docs/api/v1/http-v1-batch.md"} */ - public static String CONTENT_TYPE_GIT_LFS_JSON = "application/vnd.git-lfs+json"; + public static final String CONTENT_TYPE_GIT_LFS_JSON = "application/vnd.git-lfs+json"; /** * "arbitrary binary data" as defined in RFC 2046 * {@link "https://www.ietf.org/rfc/rfc2046.txt"} */ - public static String HDR_APPLICATION_OCTET_STREAM = "application/octet-stream"; + public static final String HDR_APPLICATION_OCTET_STREAM = "application/octet-stream"; } 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 89e9085f54..85ac88b4b3 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.5.3.qualifier" + version="4.6.2.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 a94261d347..6f75186def 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.5.3-SNAPSHOT</version> + <version>4.6.2-SNAPSHOT</version> </parent> <groupId>org.eclipse.jgit.feature</groupId> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.http.apache.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.http.apache.feature/feature.xml index 8ec3289671..e272c0b95f 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.5.3.qualifier" + version="4.6.2.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 0e05a9a65c..679f880d9a 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.5.3-SNAPSHOT</version> + <version>4.6.2-SNAPSHOT</version> </parent> <groupId>org.eclipse.jgit.feature</groupId> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/feature.properties b/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/feature.properties index 9ef46baa80..4450bbbd8b 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/feature.properties +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/feature.properties @@ -9,14 +9,13 @@ # ############################################################################### -featureName=JUnit test support for Java implementation of Git +featureName=Java implementation of Git - JUnit test support providerName=Eclipse JGit updateSiteName=Eclipse JGit Update Site # description property - text of the "Feature Description" -description=\ -JUnit test support for JGit.\n +description=JUnit test support for JGit ################ end of description property ################################## # "copyright" property - text of the "Feature Update Copyright" 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 0ec7d1813d..fe7e3acb43 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.5.3.qualifier" + version="4.6.2.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 8076aa2067..0b0a335af4 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.5.3-SNAPSHOT</version> + <version>4.6.2-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 5f0a5a5588..4aefd72ed2 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.5.3.qualifier" + version="4.6.2.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 5cf3de979b..893c49215a 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.5.3-SNAPSHOT</version> + <version>4.6.2-SNAPSHOT</version> </parent> <groupId>org.eclipse.jgit.feature</groupId> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/feature.properties b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/feature.properties index 1d1130a03b..8992ad3df1 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/feature.properties +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/feature.properties @@ -8,14 +8,14 @@ # ############################################################################### -featureName=Command Line Interface for Java implementation of Git +featureName=Java implementation of Git - Command Line Interface providerName=Eclipse JGit updateSiteName=Eclipse JGit Update Site # description property - text of the "Feature Description" description=\ -Command line interface for a pure Java implementation of the Git version control system.\n +Command line interface for a pure Java implementation of the Git version control system ################ end of description property ################################## # "copyright" property - text of the "Feature Update Copyright" 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 6b40fbb89c..81f5e7180a 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.5.3.qualifier" + version="4.6.2.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.5.0" match="equivalent"/> - <import feature="org.eclipse.jgit.lfs" version="4.5.0" match="equivalent"/> + <import feature="org.eclipse.jgit" version="4.6.1" match="equivalent"/> + <import feature="org.eclipse.jgit.lfs" version="4.6.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 9ea842f549..b6c5846de0 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.5.3-SNAPSHOT</version> + <version>4.6.2-SNAPSHOT</version> </parent> <groupId>org.eclipse.jgit.feature</groupId> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/feature.properties b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/feature.properties index 20d6641a41..012c217c59 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/feature.properties +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/feature.properties @@ -8,7 +8,7 @@ # ############################################################################### -featureName=Command Line Interface for Java implementation of Git - Source Code +featureName=Java implementation of Git - Command Line Interface - Source Code providerName=Eclipse JGit updateSiteName=Eclipse JGit Update Site 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 b2af67ed10..444a8728a3 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.5.3.qualifier" + version="4.6.2.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 6683d43d28..a35034af22 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.5.3-SNAPSHOT</version> + <version>4.6.2-SNAPSHOT</version> </parent> <groupId>org.eclipse.jgit.feature</groupId> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/category.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/category.xml index 15d10e6c30..01490295ae 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/category.xml +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/category.xml @@ -24,9 +24,9 @@ <feature url="features/org.eclipse.jgit.lfs_0.0.0.qualifier.jar" id="org.eclipse.jgit.lfs" version="0.0.0"> <category name="JGit"/> </feature> - <category-def name="JGit" label="JGit"> + <category-def name="JGit" label="Java implementation of Git"> <description> - JGit + Java implementation of Git </description> </category-def> </site> 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 2fa4e3ff39..d611d2948f 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.5.3-SNAPSHOT</version> + <version>4.6.2-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 12bee380d4..20ab58caab 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.5.3.qualifier" + version="4.6.2.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 54eb5c0273..e11e042099 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.5.3-SNAPSHOT</version> + <version>4.6.2-SNAPSHOT</version> </parent> <groupId>org.eclipse.jgit.feature</groupId> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/.classpath b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/.classpath index 098194ca4b..eca7bdba8f 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/.classpath +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/.classpath @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <classpath> - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> <classpathentry kind="src" path="src"/> <classpathentry kind="output" path="bin"/> 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 be64ac2359..cd392319e0 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 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: JGit Target Platform Bundle Bundle-SymbolicName: org.eclipse.jgit.target -Bundle-Version: 4.5.3.qualifier +Bundle-Version: 4.6.2.qualifier diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.3.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.3.tpd deleted file mode 100644 index 062e930640..0000000000 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.3.tpd +++ /dev/null @@ -1,8 +0,0 @@ -target "jgit-4.3" with source configurePhase - -include "projects/jetty-9.2.13.tpd" -include "orbit/R20150124073747-Luna-SR2.tpd" - -location "http://download.eclipse.org/releases/kepler/" { - org.eclipse.osgi lazy -} diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.4.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.4.target deleted file mode 100644 index 3451b42653..0000000000 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.4.target +++ /dev/null @@ -1,68 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<?pde?> -<!-- generated with https://github.com/mbarbero/fr.obeo.releng.targetplatform --> -<target name="jgit-4.4" sequenceNumber="1444167820"> - <locations> - <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> - <unit id="org.eclipse.jetty.client" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.client.source" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.continuation" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.continuation.source" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.http" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.http.source" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.io" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.io.source" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.security" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.security.source" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.server" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.server.source" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.servlet" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.servlet.source" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.util" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.util.source" version="9.2.13.v20150730"/> - <repository id="jetty-9.2.13" location="http://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.2.13.v20150730/"/> - </location> - <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> - <unit id="org.apache.ant" version="1.9.2.v201404171502"/> - <unit id="org.apache.ant.source" version="1.9.2.v201404171502"/> - <unit id="org.apache.commons.compress" version="1.6.0.v201310281400"/> - <unit id="org.apache.commons.compress.source" version="1.6.0.v201310281400"/> - <unit id="org.apache.commons.logging" version="1.1.1.v201101211721"/> - <unit id="org.apache.commons.logging.source" version="1.1.1.v201101211721"/> - <unit id="org.apache.httpcomponents.httpcore" version="4.3.3.v201411290715"/> - <unit id="org.apache.httpcomponents.httpcore.source" version="4.3.3.v201411290715"/> - <unit id="org.apache.httpcomponents.httpclient" version="4.3.6.v201411290715"/> - <unit id="org.apache.httpcomponents.httpclient.source" version="4.3.6.v201411290715"/> - <unit id="org.apache.log4j" version="1.2.15.v201012070815"/> - <unit id="org.apache.log4j.source" version="1.2.15.v201012070815"/> - <unit id="org.kohsuke.args4j" version="2.0.21.v201301150030"/> - <unit id="org.kohsuke.args4j.source" version="2.0.21.v201301150030"/> - <unit id="org.hamcrest.core" version="1.3.0.v201303031735"/> - <unit id="org.hamcrest.core.source" version="1.3.0.v201303031735"/> - <unit id="javaewah" version="0.7.9.v201401101600"/> - <unit id="javaewah.source" version="0.7.9.v201401101600"/> - <unit id="org.objenesis" version="1.0.0.v201105211943"/> - <unit id="org.objenesis.source" version="1.0.0.v201105211943"/> - <unit id="org.mockito" version="1.8.4.v201303031500"/> - <unit id="org.mockito.source" version="1.8.4.v201303031500"/> - <unit id="com.google.gson" version="2.2.4.v201311231704"/> - <unit id="com.jcraft.jsch" version="0.1.51.v201410302000"/> - <unit id="com.jcraft.jsch.source" version="0.1.51.v201410302000"/> - <unit id="org.junit" version="4.11.0.v201303080030"/> - <unit id="org.junit.source" version="4.11.0.v201303080030"/> - <unit id="javax.servlet" version="3.1.0.v20140303-1611"/> - <unit id="javax.servlet.source" version="3.1.0.v20140303-1611"/> - <unit id="org.tukaani.xz" version="1.3.0.v201308270617"/> - <unit id="org.tukaani.xz.source" version="1.3.0.v201308270617"/> - <unit id="org.slf4j.api" version="1.7.2.v20121108-1250"/> - <unit id="org.slf4j.api.source" version="1.7.2.v20121108-1250"/> - <unit id="org.slf4j.impl.log4j12" version="1.7.2.v20131105-2200"/> - <unit id="org.slf4j.impl.log4j12.source" version="1.7.2.v20131105-2200"/> - <repository location="http://download.eclipse.org/tools/orbit/downloads/drops/R20150124073747/repository/"/> - </location> - <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> - <unit id="org.eclipse.osgi" version="0.0.0"/> - <repository location="http://download.eclipse.org/releases/luna/"/> - </location> - </locations> -</target> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.4.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.4.tpd deleted file mode 100644 index 9b9558fbb7..0000000000 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.4.tpd +++ /dev/null @@ -1,8 +0,0 @@ -target "jgit-4.4" with source configurePhase - -include "projects/jetty-9.2.13.tpd" -include "orbit/R20150124073747-Luna-SR2.tpd" - -location "http://download.eclipse.org/releases/luna/" { - org.eclipse.osgi lazy -}
\ No newline at end of file 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 08116ebf18..85585e804a 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,26 +1,26 @@ <?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="1456522731"> +<target name="jgit-4.5" sequenceNumber="1490949900"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> - <unit id="org.eclipse.jetty.client" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.client.source" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.continuation" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.continuation.source" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.http" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.http.source" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.io" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.io.source" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.security" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.security.source" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.server" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.server.source" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.servlet" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.servlet.source" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.util" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.util.source" version="9.2.13.v20150730"/> - <repository id="jetty-9.2.13" location="http://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.2.13.v20150730/"/> + <unit id="org.eclipse.jetty.client" version="9.3.17.v20170317"/> + <unit id="org.eclipse.jetty.client.source" version="9.3.17.v20170317"/> + <unit id="org.eclipse.jetty.continuation" version="9.3.17.v20170317"/> + <unit id="org.eclipse.jetty.continuation.source" version="9.3.17.v20170317"/> + <unit id="org.eclipse.jetty.http" version="9.3.17.v20170317"/> + <unit id="org.eclipse.jetty.http.source" version="9.3.17.v20170317"/> + <unit id="org.eclipse.jetty.io" version="9.3.17.v20170317"/> + <unit id="org.eclipse.jetty.io.source" version="9.3.17.v20170317"/> + <unit id="org.eclipse.jetty.security" version="9.3.17.v20170317"/> + <unit id="org.eclipse.jetty.security.source" version="9.3.17.v20170317"/> + <unit id="org.eclipse.jetty.server" version="9.3.17.v20170317"/> + <unit id="org.eclipse.jetty.server.source" version="9.3.17.v20170317"/> + <unit id="org.eclipse.jetty.servlet" version="9.3.17.v20170317"/> + <unit id="org.eclipse.jetty.servlet.source" version="9.3.17.v20170317"/> + <unit id="org.eclipse.jetty.util" version="9.3.17.v20170317"/> + <unit id="org.eclipse.jetty.util.source" version="9.3.17.v20170317"/> + <repository id="jetty-9.3.17" location="http://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.3.17.v20170317/"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.apache.ant" version="1.9.4.v201504302020"/> @@ -61,6 +61,46 @@ <repository location="http://download.eclipse.org/tools/orbit/downloads/drops/R20160221192158/repository/"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> + <unit id="org.apache.ant" version="1.9.6.v201510161327"/> + <unit id="org.apache.ant.source" version="1.9.6.v201510161327"/> + <unit id="org.apache.commons.compress" version="1.6.0.v201310281400"/> + <unit id="org.apache.commons.compress.source" version="1.6.0.v201310281400"/> + <unit id="org.apache.commons.logging" version="1.1.1.v201101211721"/> + <unit id="org.apache.commons.logging.source" version="1.1.1.v201101211721"/> + <unit id="org.apache.httpcomponents.httpcore" version="4.3.3.v201411290715"/> + <unit id="org.apache.httpcomponents.httpcore.source" version="4.3.3.v201411290715"/> + <unit id="org.apache.httpcomponents.httpclient" version="4.3.6.v201511171540"/> + <unit id="org.apache.httpcomponents.httpclient.source" version="4.3.6.v201511171540"/> + <unit id="org.apache.log4j" version="1.2.15.v201012070815"/> + <unit id="org.apache.log4j.source" version="1.2.15.v201012070815"/> + <unit id="org.kohsuke.args4j" version="2.0.21.v201301150030"/> + <unit id="org.kohsuke.args4j.source" version="2.0.21.v201301150030"/> + <unit id="org.hamcrest.core" version="1.3.0.v201303031735"/> + <unit id="org.hamcrest.core.source" version="1.3.0.v201303031735"/> + <unit id="org.hamcrest.library" version="1.3.0.v201505072020"/> + <unit id="org.hamcrest.library.source" version="1.3.0.v201505072020"/> + <unit id="javaewah" version="1.1.6.v20160919-1400"/> + <unit id="javaewah.source" version="1.1.6.v20160919-1400"/> + <unit id="org.objenesis" version="1.0.0.v201505121915"/> + <unit id="org.objenesis.source" version="1.0.0.v201505121915"/> + <unit id="org.mockito" version="1.8.4.v201303031500"/> + <unit id="org.mockito.source" version="1.8.4.v201303031500"/> + <unit id="com.google.gson" version="2.2.4.v201311231704"/> + <unit id="com.jcraft.jsch" version="0.1.54.v20170116-1932"/> + <unit id="com.jcraft.jsch.source" version="0.1.54.v20170116-1932"/> + <unit id="org.junit" version="4.12.0.v201504281640"/> + <unit id="org.junit.source" version="4.12.0.v201504281640"/> + <unit id="javax.servlet" version="3.1.0.v201410161800"/> + <unit id="javax.servlet.source" version="3.1.0.v201410161800"/> + <unit id="org.tukaani.xz" version="1.3.0.v201308270617"/> + <unit id="org.tukaani.xz.source" version="1.3.0.v201308270617"/> + <unit id="org.slf4j.api" version="1.7.2.v20121108-1250"/> + <unit id="org.slf4j.api.source" version="1.7.2.v20121108-1250"/> + <unit id="org.slf4j.impl.log4j12" version="1.7.2.v20131105-2200"/> + <unit id="org.slf4j.impl.log4j12.source" version="1.7.2.v20131105-2200"/> + <repository location="http://download.eclipse.org/tools/orbit/downloads/drops/S20170120205402/repository"/> + </location> + <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.osgi" version="0.0.0"/> <repository location="http://download.eclipse.org/releases/mars/"/> </location> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.5.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.5.tpd index 5cd1037d16..77d3e89ee5 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.5.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.5.tpd @@ -1,7 +1,8 @@ target "jgit-4.5" with source configurePhase -include "projects/jetty-9.2.13.tpd" +include "projects/jetty-9.3.17.tpd" include "orbit/R20160221192158-Mars.tpd" +include "orbit/S20170120205402-Oxygen.tpd" location "http://download.eclipse.org/releases/mars/" { org.eclipse.osgi lazy diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.target index a1f5abf5eb..a51b4559d3 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.target @@ -1,26 +1,26 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?pde?> <!-- generated with https://github.com/mbarbero/fr.obeo.releng.targetplatform --> -<target name="jgit-4.6" sequenceNumber="1465553981"> +<target name="jgit-4.6" sequenceNumber="1490949887"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> - <unit id="org.eclipse.jetty.client" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.client.source" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.continuation" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.continuation.source" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.http" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.http.source" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.io" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.io.source" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.security" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.security.source" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.server" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.server.source" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.servlet" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.servlet.source" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.util" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.util.source" version="9.2.13.v20150730"/> - <repository id="jetty-9.2.13" location="http://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.2.13.v20150730/"/> + <unit id="org.eclipse.jetty.client" version="9.3.17.v20170317"/> + <unit id="org.eclipse.jetty.client.source" version="9.3.17.v20170317"/> + <unit id="org.eclipse.jetty.continuation" version="9.3.17.v20170317"/> + <unit id="org.eclipse.jetty.continuation.source" version="9.3.17.v20170317"/> + <unit id="org.eclipse.jetty.http" version="9.3.17.v20170317"/> + <unit id="org.eclipse.jetty.http.source" version="9.3.17.v20170317"/> + <unit id="org.eclipse.jetty.io" version="9.3.17.v20170317"/> + <unit id="org.eclipse.jetty.io.source" version="9.3.17.v20170317"/> + <unit id="org.eclipse.jetty.security" version="9.3.17.v20170317"/> + <unit id="org.eclipse.jetty.security.source" version="9.3.17.v20170317"/> + <unit id="org.eclipse.jetty.server" version="9.3.17.v20170317"/> + <unit id="org.eclipse.jetty.server.source" version="9.3.17.v20170317"/> + <unit id="org.eclipse.jetty.servlet" version="9.3.17.v20170317"/> + <unit id="org.eclipse.jetty.servlet.source" version="9.3.17.v20170317"/> + <unit id="org.eclipse.jetty.util" version="9.3.17.v20170317"/> + <unit id="org.eclipse.jetty.util.source" version="9.3.17.v20170317"/> + <repository id="jetty-9.3.17" location="http://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.3.17.v20170317/"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.apache.ant" version="1.9.6.v201510161327"/> @@ -39,15 +39,17 @@ <unit id="org.kohsuke.args4j.source" version="2.0.21.v201301150030"/> <unit id="org.hamcrest.core" version="1.3.0.v201303031735"/> <unit id="org.hamcrest.core.source" version="1.3.0.v201303031735"/> - <unit id="javaewah" version="0.7.9.v201605172130"/> - <unit id="javaewah.source" version="0.7.9.v201605172130"/> + <unit id="org.hamcrest.library" version="1.3.0.v201505072020"/> + <unit id="org.hamcrest.library.source" version="1.3.0.v201505072020"/> + <unit id="javaewah" version="1.1.6.v20160919-1400"/> + <unit id="javaewah.source" version="1.1.6.v20160919-1400"/> <unit id="org.objenesis" version="1.0.0.v201505121915"/> <unit id="org.objenesis.source" version="1.0.0.v201505121915"/> <unit id="org.mockito" version="1.8.4.v201303031500"/> <unit id="org.mockito.source" version="1.8.4.v201303031500"/> <unit id="com.google.gson" version="2.2.4.v201311231704"/> - <unit id="com.jcraft.jsch" version="0.1.53.v201508180515"/> - <unit id="com.jcraft.jsch.source" version="0.1.53.v201508180515"/> + <unit id="com.jcraft.jsch" version="0.1.54.v20170116-1932"/> + <unit id="com.jcraft.jsch.source" version="0.1.54.v20170116-1932"/> <unit id="org.junit" version="4.12.0.v201504281640"/> <unit id="org.junit.source" version="4.12.0.v201504281640"/> <unit id="javax.servlet" version="3.1.0.v201410161800"/> @@ -58,7 +60,7 @@ <unit id="org.slf4j.api.source" version="1.7.2.v20121108-1250"/> <unit id="org.slf4j.impl.log4j12" version="1.7.2.v20131105-2200"/> <unit id="org.slf4j.impl.log4j12.source" version="1.7.2.v20131105-2200"/> - <repository location="http://download.eclipse.org/tools/orbit/downloads/drops/R20160520211859/repository/"/> + <repository location="http://download.eclipse.org/tools/orbit/downloads/drops/S20170120205402/repository"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.osgi" version="0.0.0"/> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.tpd index c784c1fb0e..913f661245 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.tpd @@ -1,7 +1,7 @@ target "jgit-4.6" with source configurePhase -include "projects/jetty-9.2.13.tpd" -include "orbit/R20160520211859-Neon.tpd" +include "projects/jetty-9.3.17.tpd" +include "orbit/S20170120205402-Oxygen.tpd" location "http://download.eclipse.org/releases/neon/" { org.eclipse.osgi lazy diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.3.target b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.target index 19edf51437..541ce04ced 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.3.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.target @@ -1,68 +1,70 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?pde?> <!-- generated with https://github.com/mbarbero/fr.obeo.releng.targetplatform --> -<target name="jgit-4.3" sequenceNumber="1440024094"> +<target name="jgit-4.7" sequenceNumber="1490949871"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> - <unit id="org.eclipse.jetty.client" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.client.source" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.continuation" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.continuation.source" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.http" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.http.source" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.io" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.io.source" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.security" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.security.source" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.server" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.server.source" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.servlet" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.servlet.source" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.util" version="9.2.13.v20150730"/> - <unit id="org.eclipse.jetty.util.source" version="9.2.13.v20150730"/> - <repository id="jetty-9.2.13" location="http://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.2.13.v20150730/"/> + <unit id="org.eclipse.jetty.client" version="9.3.17.v20170317"/> + <unit id="org.eclipse.jetty.client.source" version="9.3.17.v20170317"/> + <unit id="org.eclipse.jetty.continuation" version="9.3.17.v20170317"/> + <unit id="org.eclipse.jetty.continuation.source" version="9.3.17.v20170317"/> + <unit id="org.eclipse.jetty.http" version="9.3.17.v20170317"/> + <unit id="org.eclipse.jetty.http.source" version="9.3.17.v20170317"/> + <unit id="org.eclipse.jetty.io" version="9.3.17.v20170317"/> + <unit id="org.eclipse.jetty.io.source" version="9.3.17.v20170317"/> + <unit id="org.eclipse.jetty.security" version="9.3.17.v20170317"/> + <unit id="org.eclipse.jetty.security.source" version="9.3.17.v20170317"/> + <unit id="org.eclipse.jetty.server" version="9.3.17.v20170317"/> + <unit id="org.eclipse.jetty.server.source" version="9.3.17.v20170317"/> + <unit id="org.eclipse.jetty.servlet" version="9.3.17.v20170317"/> + <unit id="org.eclipse.jetty.servlet.source" version="9.3.17.v20170317"/> + <unit id="org.eclipse.jetty.util" version="9.3.17.v20170317"/> + <unit id="org.eclipse.jetty.util.source" version="9.3.17.v20170317"/> + <repository id="jetty-9.3.17" location="http://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.3.17.v20170317/"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> - <unit id="org.apache.ant" version="1.9.2.v201404171502"/> - <unit id="org.apache.ant.source" version="1.9.2.v201404171502"/> + <unit id="org.apache.ant" version="1.9.6.v201510161327"/> + <unit id="org.apache.ant.source" version="1.9.6.v201510161327"/> <unit id="org.apache.commons.compress" version="1.6.0.v201310281400"/> <unit id="org.apache.commons.compress.source" version="1.6.0.v201310281400"/> <unit id="org.apache.commons.logging" version="1.1.1.v201101211721"/> <unit id="org.apache.commons.logging.source" version="1.1.1.v201101211721"/> <unit id="org.apache.httpcomponents.httpcore" version="4.3.3.v201411290715"/> <unit id="org.apache.httpcomponents.httpcore.source" version="4.3.3.v201411290715"/> - <unit id="org.apache.httpcomponents.httpclient" version="4.3.6.v201411290715"/> - <unit id="org.apache.httpcomponents.httpclient.source" version="4.3.6.v201411290715"/> + <unit id="org.apache.httpcomponents.httpclient" version="4.3.6.v201511171540"/> + <unit id="org.apache.httpcomponents.httpclient.source" version="4.3.6.v201511171540"/> <unit id="org.apache.log4j" version="1.2.15.v201012070815"/> <unit id="org.apache.log4j.source" version="1.2.15.v201012070815"/> <unit id="org.kohsuke.args4j" version="2.0.21.v201301150030"/> <unit id="org.kohsuke.args4j.source" version="2.0.21.v201301150030"/> <unit id="org.hamcrest.core" version="1.3.0.v201303031735"/> <unit id="org.hamcrest.core.source" version="1.3.0.v201303031735"/> - <unit id="javaewah" version="0.7.9.v201401101600"/> - <unit id="javaewah.source" version="0.7.9.v201401101600"/> - <unit id="org.objenesis" version="1.0.0.v201105211943"/> - <unit id="org.objenesis.source" version="1.0.0.v201105211943"/> + <unit id="org.hamcrest.library" version="1.3.0.v201505072020"/> + <unit id="org.hamcrest.library.source" version="1.3.0.v201505072020"/> + <unit id="javaewah" version="1.1.6.v20160919-1400"/> + <unit id="javaewah.source" version="1.1.6.v20160919-1400"/> + <unit id="org.objenesis" version="1.0.0.v201505121915"/> + <unit id="org.objenesis.source" version="1.0.0.v201505121915"/> <unit id="org.mockito" version="1.8.4.v201303031500"/> <unit id="org.mockito.source" version="1.8.4.v201303031500"/> <unit id="com.google.gson" version="2.2.4.v201311231704"/> - <unit id="com.jcraft.jsch" version="0.1.51.v201410302000"/> - <unit id="com.jcraft.jsch.source" version="0.1.51.v201410302000"/> - <unit id="org.junit" version="4.11.0.v201303080030"/> - <unit id="org.junit.source" version="4.11.0.v201303080030"/> - <unit id="javax.servlet" version="3.1.0.v20140303-1611"/> - <unit id="javax.servlet.source" version="3.1.0.v20140303-1611"/> + <unit id="com.jcraft.jsch" version="0.1.54.v20170116-1932"/> + <unit id="com.jcraft.jsch.source" version="0.1.54.v20170116-1932"/> + <unit id="org.junit" version="4.12.0.v201504281640"/> + <unit id="org.junit.source" version="4.12.0.v201504281640"/> + <unit id="javax.servlet" version="3.1.0.v201410161800"/> + <unit id="javax.servlet.source" version="3.1.0.v201410161800"/> <unit id="org.tukaani.xz" version="1.3.0.v201308270617"/> <unit id="org.tukaani.xz.source" version="1.3.0.v201308270617"/> <unit id="org.slf4j.api" version="1.7.2.v20121108-1250"/> <unit id="org.slf4j.api.source" version="1.7.2.v20121108-1250"/> <unit id="org.slf4j.impl.log4j12" version="1.7.2.v20131105-2200"/> <unit id="org.slf4j.impl.log4j12.source" version="1.7.2.v20131105-2200"/> - <repository location="http://download.eclipse.org/tools/orbit/downloads/drops/R20150124073747/repository/"/> + <repository location="http://download.eclipse.org/tools/orbit/downloads/drops/S20170120205402/repository"/> </location> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.osgi" version="0.0.0"/> - <repository location="http://download.eclipse.org/releases/kepler/"/> + <repository location="http://download.eclipse.org/releases/oxygen/"/> </location> </locations> </target> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.tpd new file mode 100644 index 0000000000..0ce8a9a0b3 --- /dev/null +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.7.tpd @@ -0,0 +1,8 @@ +target "jgit-4.7" with source configurePhase + +include "projects/jetty-9.3.17.tpd" +include "orbit/S20170120205402-Oxygen.tpd" + +location "http://download.eclipse.org/releases/oxygen/" { + org.eclipse.osgi lazy +}
\ No newline at end of file diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/S20170120205402-Oxygen.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/S20170120205402-Oxygen.tpd new file mode 100644 index 0000000000..b369cb637b --- /dev/null +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/S20170120205402-Oxygen.tpd @@ -0,0 +1,42 @@ +target "S20170120205402-Oxygen" with source configurePhase +// see http://download.eclipse.org/tools/orbit/downloads/ + +location "http://download.eclipse.org/tools/orbit/downloads/drops/S20170120205402/repository" { + org.apache.ant [1.9.6.v201510161327,1.9.6.v201510161327] + org.apache.ant.source [1.9.6.v201510161327,1.9.6.v201510161327] + org.apache.commons.compress [1.6.0.v201310281400,1.6.0.v201310281400] + org.apache.commons.compress.source [1.6.0.v201310281400,1.6.0.v201310281400] + org.apache.commons.logging [1.1.1.v201101211721,1.1.1.v201101211721] + org.apache.commons.logging.source [1.1.1.v201101211721,1.1.1.v201101211721] + org.apache.httpcomponents.httpcore [4.3.3.v201411290715,4.3.3.v201411290715] + org.apache.httpcomponents.httpcore.source [4.3.3.v201411290715,4.3.3.v201411290715] + org.apache.httpcomponents.httpclient [4.3.6.v201511171540,4.3.6.v201511171540] + org.apache.httpcomponents.httpclient.source [4.3.6.v201511171540,4.3.6.v201511171540] + org.apache.log4j [1.2.15.v201012070815,1.2.15.v201012070815] + org.apache.log4j.source [1.2.15.v201012070815,1.2.15.v201012070815] + org.kohsuke.args4j [2.0.21.v201301150030,2.0.21.v201301150030] + org.kohsuke.args4j.source [2.0.21.v201301150030,2.0.21.v201301150030] + org.hamcrest.core [1.3.0.v201303031735,1.3.0.v201303031735] + org.hamcrest.core.source [1.3.0.v201303031735,1.3.0.v201303031735] + org.hamcrest.library [1.3.0.v201505072020,1.3.0.v201505072020] + org.hamcrest.library.source [1.3.0.v201505072020,1.3.0.v201505072020] + javaewah [1.1.6.v20160919-1400,1.1.6.v20160919-1400] + javaewah.source [1.1.6.v20160919-1400,1.1.6.v20160919-1400] + org.objenesis [1.0.0.v201505121915,1.0.0.v201505121915] + org.objenesis.source [1.0.0.v201505121915,1.0.0.v201505121915] + org.mockito [1.8.4.v201303031500,1.8.4.v201303031500] + org.mockito.source [1.8.4.v201303031500,1.8.4.v201303031500] + com.google.gson [2.2.4.v201311231704,2.2.4.v201311231704] + com.jcraft.jsch [0.1.54.v20170116-1932,0.1.54.v20170116-1932] + com.jcraft.jsch.source [0.1.54.v20170116-1932,0.1.54.v20170116-1932] + org.junit [4.12.0.v201504281640,4.12.0.v201504281640] + org.junit.source [4.12.0.v201504281640,4.12.0.v201504281640] + javax.servlet [3.1.0.v201410161800,3.1.0.v201410161800] + javax.servlet.source [3.1.0.v201410161800,3.1.0.v201410161800] + org.tukaani.xz [1.3.0.v201308270617,1.3.0.v201308270617] + org.tukaani.xz.source [1.3.0.v201308270617,1.3.0.v201308270617] + org.slf4j.api [1.7.2.v20121108-1250,1.7.2.v20121108-1250] + org.slf4j.api.source [1.7.2.v20121108-1250,1.7.2.v20121108-1250] + org.slf4j.impl.log4j12 [1.7.2.v20131105-2200,1.7.2.v20131105-2200] + org.slf4j.impl.log4j12.source [1.7.2.v20131105-2200,1.7.2.v20131105-2200] +}
\ No newline at end of file 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 948947f4f2..652b122eb4 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.5.3-SNAPSHOT</version> + <version>4.6.2-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.target</artifactId> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/projects/jetty-9.2.13.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/projects/jetty-9.2.13.tpd deleted file mode 100644 index 289a73d2ae..0000000000 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/projects/jetty-9.2.13.tpd +++ /dev/null @@ -1,20 +0,0 @@ -target "jetty-9.2.13" with source configurePhase - -location jetty-9.2.13 "http://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.2.13.v20150730/" { - org.eclipse.jetty.client [9.2.13.v20150730,9.2.13.v20150730] - org.eclipse.jetty.client.source [9.2.13.v20150730,9.2.13.v20150730] - org.eclipse.jetty.continuation [9.2.13.v20150730,9.2.13.v20150730] - org.eclipse.jetty.continuation.source [9.2.13.v20150730,9.2.13.v20150730] - org.eclipse.jetty.http [9.2.13.v20150730,9.2.13.v20150730] - org.eclipse.jetty.http.source [9.2.13.v20150730,9.2.13.v20150730] - org.eclipse.jetty.io [9.2.13.v20150730,9.2.13.v20150730] - org.eclipse.jetty.io.source [9.2.13.v20150730,9.2.13.v20150730] - org.eclipse.jetty.security [9.2.13.v20150730,9.2.13.v20150730] - org.eclipse.jetty.security.source [9.2.13.v20150730,9.2.13.v20150730] - org.eclipse.jetty.server [9.2.13.v20150730,9.2.13.v20150730] - org.eclipse.jetty.server.source [9.2.13.v20150730,9.2.13.v20150730] - org.eclipse.jetty.servlet [9.2.13.v20150730,9.2.13.v20150730] - org.eclipse.jetty.servlet.source [9.2.13.v20150730,9.2.13.v20150730] - org.eclipse.jetty.util [9.2.13.v20150730,9.2.13.v20150730] - org.eclipse.jetty.util.source [9.2.13.v20150730,9.2.13.v20150730] -} diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/projects/jetty-9.3.17.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/projects/jetty-9.3.17.tpd new file mode 100644 index 0000000000..662df09f77 --- /dev/null +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/projects/jetty-9.3.17.tpd @@ -0,0 +1,20 @@ +target "jetty-9.3.17" with source configurePhase + +location jetty-9.3.17 "http://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.3.17.v20170317/" { + org.eclipse.jetty.client [9.3.17.v20170317,9.3.17.v20170317] + org.eclipse.jetty.client.source [9.3.17.v20170317,9.3.17.v20170317] + org.eclipse.jetty.continuation [9.3.17.v20170317,9.3.17.v20170317] + org.eclipse.jetty.continuation.source [9.3.17.v20170317,9.3.17.v20170317] + org.eclipse.jetty.http [9.3.17.v20170317,9.3.17.v20170317] + org.eclipse.jetty.http.source [9.3.17.v20170317,9.3.17.v20170317] + org.eclipse.jetty.io [9.3.17.v20170317,9.3.17.v20170317] + org.eclipse.jetty.io.source [9.3.17.v20170317,9.3.17.v20170317] + org.eclipse.jetty.security [9.3.17.v20170317,9.3.17.v20170317] + org.eclipse.jetty.security.source [9.3.17.v20170317,9.3.17.v20170317] + org.eclipse.jetty.server [9.3.17.v20170317,9.3.17.v20170317] + org.eclipse.jetty.server.source [9.3.17.v20170317,9.3.17.v20170317] + org.eclipse.jetty.servlet [9.3.17.v20170317,9.3.17.v20170317] + org.eclipse.jetty.servlet.source [9.3.17.v20170317,9.3.17.v20170317] + org.eclipse.jetty.util [9.3.17.v20170317,9.3.17.v20170317] + org.eclipse.jetty.util.source [9.3.17.v20170317,9.3.17.v20170317] +} diff --git a/org.eclipse.jgit.packaging/pom.xml b/org.eclipse.jgit.packaging/pom.xml index 4638dc546d..583b12831a 100644 --- a/org.eclipse.jgit.packaging/pom.xml +++ b/org.eclipse.jgit.packaging/pom.xml @@ -53,13 +53,13 @@ <groupId>org.eclipse.jgit</groupId> <artifactId>jgit.tycho.parent</artifactId> - <version>4.5.3-SNAPSHOT</version> + <version>4.6.2-SNAPSHOT</version> <packaging>pom</packaging> <name>JGit Tycho Parent</name> <properties> - <tycho-version>0.25.0</tycho-version> + <tycho-version>1.0.0</tycho-version> <tycho-extras-version>${tycho-version}</tycho-extras-version> <target-platform>jgit-4.6</target-platform> </properties> @@ -142,14 +142,14 @@ <version>${tycho-version}</version> <configuration> <encoding>UTF-8</encoding> - <source>1.7</source> - <target>1.7</target> + <source>1.8</source> + <target>1.8</target> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> - <version>2.7</version> + <version>3.0.2</version> <configuration> <encoding>ISO-8859-1</encoding> </configuration> @@ -221,7 +221,7 @@ <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>build-helper-maven-plugin</artifactId> - <version>1.10</version> + <version>1.12</version> </plugin> </plugins> </pluginManagement> diff --git a/org.eclipse.jgit.pgm.test/.classpath b/org.eclipse.jgit.pgm.test/.classpath index 30d83d8e9c..b26f4c45d1 100644 --- a/org.eclipse.jgit.pgm.test/.classpath +++ b/org.eclipse.jgit.pgm.test/.classpath @@ -2,7 +2,7 @@ <classpath> <classpathentry kind="src" path="tst"/> <classpathentry kind="src" path="src"/> - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> <classpathentry kind="output" path="bin"/> </classpath> 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 87210fb160..10c29d5576 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 @@ -7,9 +7,9 @@ org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nul org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.7 +org.eclipse.jdt.core.compiler.compliance=1.8 org.eclipse.jdt.core.compiler.debug.lineNumber=generate org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.debug.sourceFile=generate @@ -112,7 +112,7 @@ org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=error -org.eclipse.jdt.core.compiler.source=1.7 +org.eclipse.jdt.core.compiler.source=1.8 org.eclipse.jdt.core.formatter.align_type_members_on_columns=false org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 diff --git a/org.eclipse.jgit.pgm.test/BUCK b/org.eclipse.jgit.pgm.test/BUCK index a3859c9b49..cd15510798 100644 --- a/org.eclipse.jgit.pgm.test/BUCK +++ b/org.eclipse.jgit.pgm.test/BUCK @@ -21,7 +21,6 @@ for t in TESTS: '//lib:commons-compress', '//lib:tukaani-xz', ], - source_under_test = ['//org.eclipse.jgit.pgm:pgm'], vm_args = ['-Xmx256m', '-Dfile.encoding=UTF-8'], ) diff --git a/org.eclipse.jgit.pgm.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.pgm.test/META-INF/MANIFEST.MF index 101670cc9c..8e7d5abe2c 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 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Bundle-SymbolicName: org.eclipse.jgit.pgm.test -Bundle-Version: 4.5.3.qualifier +Bundle-Version: 4.6.2.qualifier Bundle-Vendor: %provider_name Bundle-Localization: plugin Bundle-ActivationPolicy: lazy -Bundle-RequiredExecutionEnvironment: JavaSE-1.7 -Import-Package: org.eclipse.jgit.api;version="[4.5.3,4.6.0)", - org.eclipse.jgit.api.errors;version="[4.5.3,4.6.0)", - org.eclipse.jgit.diff;version="[4.5.3,4.6.0)", - org.eclipse.jgit.dircache;version="[4.5.3,4.6.0)", - org.eclipse.jgit.internal.storage.file;version="4.5.3", - org.eclipse.jgit.junit;version="[4.5.3,4.6.0)", - org.eclipse.jgit.lib;version="[4.5.3,4.6.0)", - org.eclipse.jgit.merge;version="[4.5.3,4.6.0)", - org.eclipse.jgit.pgm;version="[4.5.3,4.6.0)", - org.eclipse.jgit.pgm.internal;version="[4.5.3,4.6.0)", - org.eclipse.jgit.pgm.opt;version="[4.5.3,4.6.0)", - org.eclipse.jgit.revwalk;version="[4.5.3,4.6.0)", - org.eclipse.jgit.storage.file;version="[4.5.3,4.6.0)", - org.eclipse.jgit.transport;version="[4.5.3,4.6.0)", - org.eclipse.jgit.treewalk;version="[4.5.3,4.6.0)", - org.eclipse.jgit.util;version="[4.5.3,4.6.0)", - org.eclipse.jgit.util.io;version="[4.5.3,4.6.0)", +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)", 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/org.eclipse.jgit.pgm--All-Tests (Java7).launch b/org.eclipse.jgit.pgm.test/org.eclipse.jgit.pgm--All-Tests (Java7).launch deleted file mode 100644 index 3df0dcb645..0000000000 --- a/org.eclipse.jgit.pgm.test/org.eclipse.jgit.pgm--All-Tests (Java7).launch +++ /dev/null @@ -1,21 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<launchConfiguration type="org.eclipse.jdt.junit.launchconfig"> -<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS"> -<listEntry value="/org.eclipse.jgit.pgm.test/tst"/> -</listAttribute> -<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES"> -<listEntry value="2"/> -</listAttribute> -<booleanAttribute key="org.eclipse.debug.core.appendEnvironmentVariables" value="true"/> -<listAttribute key="org.eclipse.debug.ui.favoriteGroups"> -<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/> -<listEntry value="org.eclipse.debug.ui.launchGroup.run"/> -</listAttribute> -<stringAttribute key="org.eclipse.jdt.junit.CONTAINER" value="=org.eclipse.jgit.pgm.test/tst"/> -<booleanAttribute key="org.eclipse.jdt.junit.KEEPRUNNING_ATTR" value="false"/> -<stringAttribute key="org.eclipse.jdt.junit.TESTNAME" value=""/> -<stringAttribute key="org.eclipse.jdt.junit.TEST_KIND" value="org.eclipse.jdt.junit.loader.junit4"/> -<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/> -<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value=""/> -<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="org.eclipse.jgit.pgm.test"/> -</launchConfiguration> diff --git a/org.eclipse.jgit.pgm.test/org.eclipse.jgit.pgm--All-Tests (Java8) (de).launch b/org.eclipse.jgit.pgm.test/org.eclipse.jgit.pgm--All-Tests (Java8) (de).launch index 5c137f28fe..e11b72f45e 100644 --- a/org.eclipse.jgit.pgm.test/org.eclipse.jgit.pgm--All-Tests (Java8) (de).launch +++ b/org.eclipse.jgit.pgm.test/org.eclipse.jgit.pgm--All-Tests (Java8) (de).launch @@ -20,7 +20,7 @@ <stringAttribute key="org.eclipse.jdt.junit.TEST_KIND" value="org.eclipse.jdt.junit.loader.junit4"/> <booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="true"/> <listAttribute key="org.eclipse.jdt.launching.CLASSPATH"> -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry containerPath="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7" path="1" type="4"/> "/> +<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry containerPath="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8" path="1" type="4"/> "/> <listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry id="org.eclipse.jdt.launching.classpathentry.defaultClasspath"> <memento exportedEntriesOnly="false" project="org.eclipse.jgit.pgm.test"/> </runtimeClasspathEntry> "/> </listAttribute> <booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/> diff --git a/org.eclipse.jgit.pgm.test/org.eclipse.jgit.pgm--All-Tests (Java8).launch b/org.eclipse.jgit.pgm.test/org.eclipse.jgit.pgm--All-Tests (Java8).launch index ce473ed03d..8b0452afee 100644 --- a/org.eclipse.jgit.pgm.test/org.eclipse.jgit.pgm--All-Tests (Java8).launch +++ b/org.eclipse.jgit.pgm.test/org.eclipse.jgit.pgm--All-Tests (Java8).launch @@ -17,7 +17,7 @@ <stringAttribute key="org.eclipse.jdt.junit.TEST_KIND" value="org.eclipse.jdt.junit.loader.junit4"/> <booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="true"/> <listAttribute key="org.eclipse.jdt.launching.CLASSPATH"> -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry containerPath="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7" path="1" type="4"/> "/> +<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry containerPath="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8" path="1" type="4"/> "/> <listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry id="org.eclipse.jdt.launching.classpathentry.defaultClasspath"> <memento exportedEntriesOnly="false" project="org.eclipse.jgit.pgm.test"/> </runtimeClasspathEntry> "/> </listAttribute> <booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/> diff --git a/org.eclipse.jgit.pgm.test/pom.xml b/org.eclipse.jgit.pgm.test/pom.xml index 894bf35b18..c8188cb717 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.5.3-SNAPSHOT</version> + <version>4.6.2-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 a6af077aa5..b675d3c31d 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 @@ -62,15 +62,11 @@ public class CLIRepositoryTestCase extends LocalDiskRepositoryTestCase { /** Test repository, initialized for this test case. */ protected Repository db; - /** Working directory of {@link #db}. */ - protected File trash; - @Override @Before public void setUp() throws Exception { super.setUp(); db = createWorkRepository(); - trash = db.getWorkTree(); } /** 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 3f396563c2..b08bc8afe7 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 @@ -46,7 +46,6 @@ import static org.junit.Assert.assertNull; import java.io.ByteArrayOutputStream; import java.io.File; - import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; @@ -218,7 +217,7 @@ public class CLIGitCommand extends Main { inquote = !inquote; continue; case '\\': - if (inquote || ip == commandLine.length()) + if (inDblQuote || inquote || ip == commandLine.length()) r.append(b); // literal within a quote else r.append(commandLine.charAt(ip++)); 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 a503ffdad0..35467c6304 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 @@ -528,15 +528,15 @@ public class ArchiveTest extends CLIRepositoryTestCase { @Test public void testArchiveWithLongFilename() throws Exception { - String filename = ""; + StringBuilder filename = new StringBuilder(); List<String> l = new ArrayList<String>(); for (int i = 0; i < 20; i++) { - filename = filename + "1234567890/"; - l.add(filename); + filename.append("1234567890/"); + l.add(filename.toString()); } - filename = filename + "1234567890"; - l.add(filename); - writeTrashFile(filename, "file with long path"); + filename.append("1234567890"); + l.add(filename.toString()); + writeTrashFile(filename.toString(), "file with long path"); git.add().addFilepattern("1234567890").call(); git.commit().setMessage("file with long name").call(); @@ -548,15 +548,15 @@ public class ArchiveTest extends CLIRepositoryTestCase { @Test public void testTarWithLongFilename() throws Exception { - String filename = ""; + StringBuilder filename = new StringBuilder(); List<String> l = new ArrayList<String>(); for (int i = 0; i < 20; i++) { - filename = filename + "1234567890/"; - l.add(filename); + filename.append("1234567890/"); + l.add(filename.toString()); } - filename = filename + "1234567890"; - l.add(filename); - writeTrashFile(filename, "file with long path"); + filename.append("1234567890"); + l.add(filename.toString()); + writeTrashFile(filename.toString(), "file with long path"); git.add().addFilepattern("1234567890").call(); git.commit().setMessage("file with long name").call(); diff --git a/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/CLIGitCommandTest.java b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/CLIGitCommandTest.java index 24788a47bd..58d8e0349f 100644 --- a/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/CLIGitCommandTest.java +++ b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/CLIGitCommandTest.java @@ -51,9 +51,11 @@ public class CLIGitCommandTest { @Test public void testSplit() throws Exception { + assertArrayEquals(new String[0], split("")); assertArrayEquals(new String[] { "a" }, split("a")); assertArrayEquals(new String[] { "a", "b" }, split("a b")); assertArrayEquals(new String[] { "a", "b c" }, split("a 'b c'")); assertArrayEquals(new String[] { "a", "b c" }, split("a \"b c\"")); + assertArrayEquals(new String[] { "a", "b\\c" }, split("a \"b\\c\"")); } } diff --git a/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/CheckoutTest.java b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/CheckoutTest.java index 3651542fc6..4b86b6014e 100644 --- a/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/CheckoutTest.java +++ b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/CheckoutTest.java @@ -613,7 +613,30 @@ public class CheckoutTest extends CLIRepositoryTestCase { } @Test - public void testCheckouSingleFile() throws Exception { + public void testCheckoutAllPaths() throws Exception { + try (Git git = new Git(db)) { + writeTrashFile("a", "Hello world a"); + git.add().addFilepattern(".").call(); + git.commit().setMessage("commit file a").call(); + git.branchCreate().setName("branch_1").call(); + git.checkout().setName("branch_1").call(); + File b = writeTrashFile("b", "Hello world b"); + git.add().addFilepattern("b").call(); + git.commit().setMessage("commit file b").call(); + File a = writeTrashFile("a", "New Hello world a"); + git.add().addFilepattern(".").call(); + git.commit().setMessage("modified a").call(); + assertArrayEquals(new String[] { "" }, + execute("git checkout HEAD~2 -- .")); + assertEquals("Hello world a", read(a)); + assertArrayEquals(new String[] { "* branch_1", " master", "" }, + execute("git branch")); + assertEquals("Hello world b", read(b)); + } + } + + @Test + public void testCheckoutSingleFile() throws Exception { try (Git git = new Git(db)) { File a = writeTrashFile("a", "file a"); git.add().addFilepattern(".").call(); diff --git a/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/CleanTest.java b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/CleanTest.java index bbac296f16..82c0d989fc 100644 --- a/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/CleanTest.java +++ b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/CleanTest.java @@ -42,13 +42,14 @@ */ package org.eclipse.jgit.pgm; -import org.eclipse.jgit.api.Git; -import org.eclipse.jgit.lib.CLIRepositoryTestCase; -import org.junit.Test; import static org.eclipse.jgit.junit.JGitTestUtil.check; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.lib.CLIRepositoryTestCase; +import org.junit.Test; public class CleanTest extends CLIRepositoryTestCase { @Test diff --git a/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/ProxyConfigTest.java b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/ProxyConfigTest.java new file mode 100644 index 0000000000..06e7a1dbe6 --- /dev/null +++ b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/ProxyConfigTest.java @@ -0,0 +1,232 @@ +/* + * Copyright (C) 2016, Chrisian Halstrick <christian.halstrick@sap.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.pgm; + +import static org.junit.Assert.assertEquals; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.net.MalformedURLException; +import java.util.List; +import java.util.Map; + +import org.junit.Before; +import org.junit.Test; + +/** + * Test how the content of the environment variables http[s]_proxy (upper- and + * lowercase) influence the setting of the system properties + * http[s].proxy[Host|Port] + */ +public class ProxyConfigTest { + private ProcessBuilder processBuilder; + + private Map<String, String> environment; + + @Before + public void setUp() { + String separator = System.getProperty("file.separator"); + String classpath = System.getProperty("java.class.path"); + String path = System.getProperty("java.home") + separator + "bin" + + separator + "java"; + processBuilder = new ProcessBuilder(path, "-cp", classpath, + ProxyPropertiesDumper.class.getName()); + environment = processBuilder.environment(); + environment.remove("http_proxy"); + environment.remove("https_proxy"); + environment.remove("HTTP_PROXY"); + environment.remove("HTTPS_PROXY"); + } + + @Test + public void testNoSetting() throws Exception { + Process start = processBuilder.start(); + start.waitFor(); + assertEquals( + "http.proxyHost: null, http.proxyPort: null, https.proxyHost: null, https.proxyPort: null", + getOutput(start)); + } + + @Test + public void testHttpProxy_lowerCase() throws Exception { + environment.put("http_proxy", "http://xx:1234"); + Process start = processBuilder.start(); + start.waitFor(); + assertEquals( + "http.proxyHost: xx, http.proxyPort: 1234, https.proxyHost: null, https.proxyPort: null", + getOutput(start)); + } + + @Test + public void testHttpProxy_upperCase() throws Exception { + environment.put("HTTP_PROXY", "http://XX:1234"); + Process start = processBuilder.start(); + start.waitFor(); + assertEquals( + "http.proxyHost: null, http.proxyPort: null, https.proxyHost: null, https.proxyPort: null", + getOutput(start)); + } + + @Test + public void testHttpProxy_bothCases() throws Exception { + environment.put("http_proxy", "http://xx:1234"); + environment.put("HTTP_PROXY", "http://XX:1234"); + Process start = processBuilder.start(); + start.waitFor(); + assertEquals( + "http.proxyHost: xx, http.proxyPort: 1234, https.proxyHost: null, https.proxyPort: null", + getOutput(start)); + } + + @Test + public void testHttpsProxy_lowerCase() throws Exception { + environment.put("https_proxy", "http://xx:1234"); + Process start = processBuilder.start(); + start.waitFor(); + assertEquals( + "http.proxyHost: null, http.proxyPort: null, https.proxyHost: xx, https.proxyPort: 1234", + getOutput(start)); + } + + @Test + public void testHttpsProxy_upperCase() throws Exception { + environment.put("HTTPS_PROXY", "http://XX:1234"); + Process start = processBuilder.start(); + start.waitFor(); + assertEquals( + "http.proxyHost: null, http.proxyPort: null, https.proxyHost: XX, https.proxyPort: 1234", + getOutput(start)); + } + + @Test + public void testHttpsProxy_bothCases() throws Exception { + environment.put("https_proxy", "http://xx:1234"); + environment.put("HTTPS_PROXY", "http://XX:1234"); + Process start = processBuilder.start(); + start.waitFor(); + assertEquals( + "http.proxyHost: null, http.proxyPort: null, https.proxyHost: xx, https.proxyPort: 1234", + getOutput(start)); + } + + @Test + public void testAll() throws Exception { + environment.put("http_proxy", "http://xx:1234"); + environment.put("HTTP_PROXY", "http://XX:1234"); + environment.put("https_proxy", "http://yy:1234"); + environment.put("HTTPS_PROXY", "http://YY:1234"); + Process start = processBuilder.start(); + start.waitFor(); + assertEquals( + "http.proxyHost: xx, http.proxyPort: 1234, https.proxyHost: yy, https.proxyPort: 1234", + getOutput(start)); + } + + @Test + public void testDontOverwriteHttp() + throws IOException, InterruptedException { + environment.put("http_proxy", "http://xx:1234"); + environment.put("HTTP_PROXY", "http://XX:1234"); + environment.put("https_proxy", "http://yy:1234"); + environment.put("HTTPS_PROXY", "http://YY:1234"); + List<String> command = processBuilder.command(); + command.add(1, "-Dhttp.proxyHost=gondola"); + command.add(2, "-Dhttp.proxyPort=5678"); + command.add("dontClearProperties"); + Process start = processBuilder.start(); + start.waitFor(); + assertEquals( + "http.proxyHost: gondola, http.proxyPort: 5678, https.proxyHost: yy, https.proxyPort: 1234", + getOutput(start)); + } + + @Test + public void testOverwriteHttpPort() + throws IOException, InterruptedException { + environment.put("http_proxy", "http://xx:1234"); + environment.put("HTTP_PROXY", "http://XX:1234"); + environment.put("https_proxy", "http://yy:1234"); + environment.put("HTTPS_PROXY", "http://YY:1234"); + List<String> command = processBuilder.command(); + command.add(1, "-Dhttp.proxyPort=5678"); + command.add("dontClearProperties"); + Process start = processBuilder.start(); + start.waitFor(); + assertEquals( + "http.proxyHost: xx, http.proxyPort: 1234, https.proxyHost: yy, https.proxyPort: 1234", + getOutput(start)); + } + + private static String getOutput(Process p) + throws IOException, UnsupportedEncodingException { + try (InputStream inputStream = p.getInputStream()) { + ByteArrayOutputStream result = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024]; + int length; + while ((length = inputStream.read(buffer)) != -1) { + result.write(buffer, 0, length); + } + return result.toString("UTF-8"); + } + } +} + +class ProxyPropertiesDumper { + public static void main(String args[]) { + try { + if (args.length == 0 || !args[0].equals("dontClearProperties")) { + System.clearProperty("http.proxyHost"); + System.clearProperty("http.proxyPort"); + System.clearProperty("https.proxyHost"); + System.clearProperty("https.proxyPort"); + } + Main.configureHttpProxy(); + System.out.printf( + "http.proxyHost: %s, http.proxyPort: %s, https.proxyHost: %s, https.proxyPort: %s", + System.getProperty("http.proxyHost"), + System.getProperty("http.proxyPort"), + System.getProperty("https.proxyHost"), + System.getProperty("https.proxyPort")); + System.out.flush(); + } catch (MalformedURLException e) { + System.out.println("exception: " + e); + } + } +} diff --git a/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/ResetTest.java b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/ResetTest.java index 16c5889c48..44a7630c8a 100644 --- a/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/ResetTest.java +++ b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/ResetTest.java @@ -42,7 +42,10 @@ */ package org.eclipse.jgit.pgm; -import static org.junit.Assert.*; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import org.eclipse.jgit.api.Git; import org.eclipse.jgit.lib.CLIRepositoryTestCase; diff --git a/org.eclipse.jgit.pgm/.classpath b/org.eclipse.jgit.pgm/.classpath index c5d5a577b5..e8bc97759e 100644 --- a/org.eclipse.jgit.pgm/.classpath +++ b/org.eclipse.jgit.pgm/.classpath @@ -3,7 +3,7 @@ <classpathentry kind="src" path="src"/> <classpathentry excluding="*|resources/|resources/" including="META-INF/" kind="src" path=""/> <classpathentry kind="src" path="resources"/> - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> <classpathentry kind="output" path="bin"/> </classpath> 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 bfaf736d6e..4f1759fb3f 100644 --- a/org.eclipse.jgit.pgm/.settings/org.eclipse.jdt.core.prefs +++ b/org.eclipse.jgit.pgm/.settings/org.eclipse.jdt.core.prefs @@ -7,9 +7,9 @@ org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jgit.annotations.N org.eclipse.jdt.core.compiler.annotation.nullanalysis=enabled org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.7 +org.eclipse.jdt.core.compiler.compliance=1.8 org.eclipse.jdt.core.compiler.debug.lineNumber=generate org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.debug.sourceFile=generate @@ -112,7 +112,7 @@ org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=error -org.eclipse.jdt.core.compiler.source=1.7 +org.eclipse.jdt.core.compiler.source=1.8 org.eclipse.jdt.core.formatter.align_type_members_on_columns=false org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 diff --git a/org.eclipse.jgit.pgm/BUCK b/org.eclipse.jgit.pgm/BUCK index 47711b5c6b..5d5e6f7095 100644 --- a/org.eclipse.jgit.pgm/BUCK +++ b/org.eclipse.jgit.pgm/BUCK @@ -9,6 +9,7 @@ java_library( '//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', diff --git a/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF b/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF index 968e8d38e5..5c30da7547 100644 --- a/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF @@ -2,69 +2,71 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Bundle-SymbolicName: org.eclipse.jgit.pgm -Bundle-Version: 4.5.3.qualifier +Bundle-Version: 4.6.2.qualifier Bundle-Vendor: %provider_name Bundle-ActivationPolicy: lazy Bundle-Localization: plugin -Bundle-RequiredExecutionEnvironment: JavaSE-1.7 +Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Import-Package: javax.servlet;version="[3.1.0,4.0.0)", javax.servlet.http;version="[3.1.0,4.0.0)", org.apache.commons.compress.archivers;version="[1.3,2.0)", org.apache.commons.compress.archivers.tar;version="[1.3,2.0)", org.apache.commons.compress.archivers.zip;version="[1.3,2.0)", - org.eclipse.jetty.continuation;version="[9.0.0,10.0.0)", - org.eclipse.jetty.http;version="[9.0.0,10.0.0)", - org.eclipse.jetty.io;version="[9.0.0,10.0.0)", - org.eclipse.jetty.security;version="[9.0.0,10.0.0)", - org.eclipse.jetty.security.authentication;version="[9.0.0,10.0.0)", - org.eclipse.jetty.server;version="[9.0.0,10.0.0)", - org.eclipse.jetty.server.handler;version="[9.0.0,10.0.0)", - org.eclipse.jetty.server.nio;version="[9.0.0,10.0.0)", - org.eclipse.jetty.servlet;version="[9.0.0,10.0.0)", - org.eclipse.jetty.util;version="[9.0.0,10.0.0)", - org.eclipse.jetty.util.component;version="[9.0.0,10.0.0)", - org.eclipse.jetty.util.log;version="[9.0.0,10.0.0)", - org.eclipse.jetty.util.security;version="[9.0.0,10.0.0)", - org.eclipse.jetty.util.thread;version="[9.0.0,10.0.0)", - org.eclipse.jgit.api;version="[4.5.3,4.6.0)", - org.eclipse.jgit.api.errors;version="[4.5.3,4.6.0)", - org.eclipse.jgit.archive;version="[4.5.3,4.6.0)", - org.eclipse.jgit.awtui;version="[4.5.3,4.6.0)", - org.eclipse.jgit.blame;version="[4.5.3,4.6.0)", - org.eclipse.jgit.diff;version="[4.5.3,4.6.0)", - org.eclipse.jgit.dircache;version="[4.5.3,4.6.0)", - org.eclipse.jgit.errors;version="[4.5.3,4.6.0)", - org.eclipse.jgit.gitrepo;version="[4.5.3,4.6.0)", - org.eclipse.jgit.internal.ketch;version="[4.5.3,4.6.0)", - org.eclipse.jgit.internal.storage.file;version="[4.5.3,4.6.0)", - org.eclipse.jgit.internal.storage.pack;version="[4.5.3,4.6.0)", - org.eclipse.jgit.internal.storage.reftree;version="[4.5.3,4.6.0)", - org.eclipse.jgit.lfs.lib;version="[4.5.3,4.6.0)", - org.eclipse.jgit.lfs.server;version="[4.5.3,4.6.0)", - org.eclipse.jgit.lfs.server.fs;version="[4.5.3,4.6.0)", - org.eclipse.jgit.lfs.server.s3;version="[4.5.3,4.6.0)", - org.eclipse.jgit.lib;version="[4.5.3,4.6.0)", - org.eclipse.jgit.merge;version="[4.5.3,4.6.0)", - org.eclipse.jgit.nls;version="[4.5.3,4.6.0)", - org.eclipse.jgit.notes;version="[4.5.3,4.6.0)", - org.eclipse.jgit.revplot;version="[4.5.3,4.6.0)", - org.eclipse.jgit.revwalk;version="[4.5.3,4.6.0)", - org.eclipse.jgit.revwalk.filter;version="[4.5.3,4.6.0)", - org.eclipse.jgit.storage.file;version="[4.5.3,4.6.0)", - org.eclipse.jgit.storage.pack;version="[4.5.3,4.6.0)", - org.eclipse.jgit.transport;version="[4.5.3,4.6.0)", - org.eclipse.jgit.transport.http.apache;version="[4.5.3,4.6.0)", - org.eclipse.jgit.transport.resolver;version="[4.5.3,4.6.0)", - org.eclipse.jgit.treewalk;version="[4.5.3,4.6.0)", - org.eclipse.jgit.treewalk.filter;version="[4.5.3,4.6.0)", - org.eclipse.jgit.util;version="[4.5.3,4.6.0)", - org.eclipse.jgit.util.io;version="[4.5.3,4.6.0)", + org.apache.commons.logging;version="1.1.1", + org.eclipse.jetty.continuation;version="[9.0.0,9.4.0)", + org.eclipse.jetty.http;version="[9.0.0,9.4.0)", + org.eclipse.jetty.io;version="[9.0.0,9.4.0)", + org.eclipse.jetty.security;version="[9.0.0,9.4.0)", + org.eclipse.jetty.security.authentication;version="[9.0.0,9.4.0)", + org.eclipse.jetty.server;version="[9.0.0,9.4.0)", + org.eclipse.jetty.server.handler;version="[9.0.0,9.4.0)", + org.eclipse.jetty.server.nio;version="[9.0.0,9.4.0)", + org.eclipse.jetty.servlet;version="[9.0.0,9.4.0)", + org.eclipse.jetty.util;version="[9.0.0,9.4.0)", + 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.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.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.5.3"; +Export-Package: org.eclipse.jgit.console;version="4.6.2"; uses:="org.eclipse.jgit.transport, org.eclipse.jgit.util", - org.eclipse.jgit.pgm;version="4.5.3"; + org.eclipse.jgit.pgm;version="4.6.2"; uses:="org.eclipse.jgit.revwalk, org.eclipse.jgit.treewalk.filter, org.eclipse.jgit.pgm.opt, @@ -75,11 +77,11 @@ Export-Package: org.eclipse.jgit.console;version="4.5.3"; org.eclipse.jgit.treewalk, javax.swing, org.eclipse.jgit.transport", - org.eclipse.jgit.pgm.debug;version="4.5.3"; + org.eclipse.jgit.pgm.debug;version="4.6.2"; uses:="org.eclipse.jgit.util.io, org.eclipse.jgit.pgm", - org.eclipse.jgit.pgm.internal;version="4.5.3";x-friends:="org.eclipse.jgit.pgm.test,org.eclipse.jgit.test", - org.eclipse.jgit.pgm.opt;version="4.5.3"; + 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"; 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 d790bfd9ec..443ccc8c3f 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-ManifestVersion: 2 Bundle-Name: org.eclipse.jgit.pgm - Sources Bundle-SymbolicName: org.eclipse.jgit.pgm.source Bundle-Vendor: Eclipse.org - JGit -Bundle-Version: 4.5.3.qualifier -Eclipse-SourceBundle: org.eclipse.jgit.pgm;version="4.5.3.qualifier";roots="." +Bundle-Version: 4.6.2.qualifier +Eclipse-SourceBundle: org.eclipse.jgit.pgm;version="4.6.2.qualifier";roots="." diff --git a/org.eclipse.jgit.pgm/pom.xml b/org.eclipse.jgit.pgm/pom.xml index b66d0350cd..c6f4aca0df 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.5.3-SNAPSHOT</version> + <version>4.6.2-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.pgm</artifactId> diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/console/ConsoleAuthenticator.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/console/ConsoleAuthenticator.java index bdaccb0657..8bf451c3cb 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/console/ConsoleAuthenticator.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/console/ConsoleAuthenticator.java @@ -49,9 +49,8 @@ import java.net.Authenticator; import java.net.PasswordAuthentication; import java.text.MessageFormat; -import org.eclipse.jgit.util.CachedAuthenticator; - import org.eclipse.jgit.pgm.internal.CLIText; +import org.eclipse.jgit.util.CachedAuthenticator; /** * Basic network prompt for username/password when using the console. diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/console/ConsoleCredentialsProvider.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/console/ConsoleCredentialsProvider.java index e805add814..0aa0cf4846 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/console/ConsoleCredentialsProvider.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/console/ConsoleCredentialsProvider.java @@ -48,14 +48,13 @@ package org.eclipse.jgit.console; import java.io.Console; import org.eclipse.jgit.errors.UnsupportedCredentialItem; +import org.eclipse.jgit.pgm.internal.CLIText; import org.eclipse.jgit.transport.ChainingCredentialsProvider; import org.eclipse.jgit.transport.CredentialItem; import org.eclipse.jgit.transport.CredentialsProvider; import org.eclipse.jgit.transport.NetRCCredentialsProvider; import org.eclipse.jgit.transport.URIish; -import org.eclipse.jgit.pgm.internal.CLIText; - /** * Interacts with the user during authentication by using the text console. * diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Archive.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Archive.java index fe2ba83bc6..cff0bf6c2b 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Archive.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Archive.java @@ -52,7 +52,6 @@ import org.eclipse.jgit.api.Git; import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.archive.ArchiveFormats; import org.eclipse.jgit.lib.ObjectId; -import org.eclipse.jgit.pgm.TextBuiltin; import org.eclipse.jgit.pgm.internal.CLIText; import org.kohsuke.args4j.Argument; import org.kohsuke.args4j.Option; 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 94517dbf2f..0c3b720fb6 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 @@ -92,8 +92,11 @@ class Checkout extends TextBuiltin { CheckoutCommand command = git.checkout(); if (paths.size() > 0) { command.setStartPoint(name); - for (String path : paths) - command.addPath(path); + if (paths.size() == 1 && paths.get(0).equals(".")) { //$NON-NLS-1$ + command.setAllPaths(true); + } else { + command.addPaths(paths); + } } else { command.setCreateBranch(createBranch); command.setName(name); 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 32adf6df0c..95c2132435 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 @@ -47,14 +47,14 @@ package org.eclipse.jgit.pgm; import java.util.ArrayList; import java.util.List; -import org.kohsuke.args4j.Argument; -import org.kohsuke.args4j.Option; import org.eclipse.jgit.lib.FileMode; import org.eclipse.jgit.pgm.opt.PathTreeFilterHandler; import org.eclipse.jgit.treewalk.AbstractTreeIterator; import org.eclipse.jgit.treewalk.TreeWalk; import org.eclipse.jgit.treewalk.filter.AndTreeFilter; import org.eclipse.jgit.treewalk.filter.TreeFilter; +import org.kohsuke.args4j.Argument; +import org.kohsuke.args4j.Option; @Command(usage = "usage_ShowDiffTree") class DiffTree extends TextBuiltin { 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 d701f22c38..a0f4d06d40 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 @@ -57,6 +57,8 @@ import java.util.List; import org.eclipse.jgit.awtui.AwtAuthenticator; import org.eclipse.jgit.awtui.AwtCredentialsProvider; import org.eclipse.jgit.errors.TransportException; +import org.eclipse.jgit.lfs.CleanFilter; +import org.eclipse.jgit.lfs.SmudgeFilter; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.RepositoryBuilder; import org.eclipse.jgit.pgm.internal.CLIText; @@ -97,6 +99,8 @@ public class Main { */ public Main() { HttpTransport.setConnectionFactory(new HttpClientConnectionFactory()); + CleanFilter.register(); + SmudgeFilter.register(); } /** @@ -339,17 +343,28 @@ public class Main { * <code>https_proxy</code> environment variables as a means of specifying * an HTTP/S proxy for requests made behind a firewall. This is not natively * recognized by the JRE, so this method can be used by command line - * utilities to configure the JRE before the first request is sent. + * utilities to configure the JRE before the first request is sent. The + * information found in the environment variables is copied to the + * associated system properties. This is not done when the system properties + * are already set. The default way of telling java programs about proxies + * (the system properties) takes precedence over environment variables. * * @throws MalformedURLException * the value in <code>http_proxy</code> or * <code>https_proxy</code> is unsupportable. */ - private static void configureHttpProxy() throws MalformedURLException { + static void configureHttpProxy() throws MalformedURLException { for (String protocol : new String[] { "http", "https" }) { //$NON-NLS-1$ //$NON-NLS-2$ - final String s = System.getenv(protocol + "_proxy"); //$NON-NLS-1$ - if (s == null || s.equals("")) //$NON-NLS-1$ - return; + if (System.getProperty(protocol + ".proxyHost") != null) { //$NON-NLS-1$ + continue; + } + String s = System.getenv(protocol + "_proxy"); //$NON-NLS-1$ + if (s == null && protocol.equals("https")) { //$NON-NLS-1$ + s = System.getenv("HTTPS_PROXY"); //$NON-NLS-1$ + } + if (s == null || s.equals("")) { //$NON-NLS-1$ + continue; + } final URL u = new URL( (s.indexOf("://") == -1) ? protocol + "://" + s : s); //$NON-NLS-1$ //$NON-NLS-2$ diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Merge.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Merge.java index 485efc5428..1aab748a0c 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Merge.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Merge.java @@ -49,8 +49,8 @@ import java.util.Map; import org.eclipse.jgit.api.Git; import org.eclipse.jgit.api.MergeCommand; -import org.eclipse.jgit.api.MergeResult; import org.eclipse.jgit.api.MergeCommand.FastForwardMode; +import org.eclipse.jgit.api.MergeResult; import org.eclipse.jgit.api.errors.CheckoutConflictException; import org.eclipse.jgit.lib.AnyObjectId; import org.eclipse.jgit.lib.Constants; 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 29cbb53a98..9dcd5129b6 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 @@ -47,10 +47,10 @@ package org.eclipse.jgit.pgm; import java.util.ArrayList; import java.util.List; -import org.kohsuke.args4j.Argument; -import org.kohsuke.args4j.Option; import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.filter.RevFilter; +import org.kohsuke.args4j.Argument; +import org.kohsuke.args4j.Option; @Command(usage = "usage_MergeBase") class MergeBase extends TextBuiltin { 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 c5ecb8496e..6833ad3c05 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 @@ -51,13 +51,13 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; -import org.kohsuke.args4j.Argument; -import org.kohsuke.args4j.CmdLineException; -import org.kohsuke.args4j.Option; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.pgm.internal.CLIText; import org.eclipse.jgit.pgm.opt.CmdLineParser; +import org.kohsuke.args4j.Argument; +import org.kohsuke.args4j.CmdLineException; +import org.kohsuke.args4j.Option; @Command(usage = "usage_RevParse") class RevParse extends TextBuiltin { 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 d6063c31b4..1543586802 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 @@ -49,8 +49,6 @@ import java.util.EnumSet; import java.util.List; import java.util.Map; -import org.kohsuke.args4j.Argument; -import org.kohsuke.args4j.Option; import org.eclipse.jgit.diff.DiffConfig; import org.eclipse.jgit.errors.IncorrectObjectTypeException; import org.eclipse.jgit.lib.Constants; @@ -73,6 +71,8 @@ import org.eclipse.jgit.revwalk.filter.MessageRevFilter; import org.eclipse.jgit.revwalk.filter.RevFilter; import org.eclipse.jgit.treewalk.filter.AndTreeFilter; import org.eclipse.jgit.treewalk.filter.TreeFilter; +import org.kohsuke.args4j.Argument; +import org.kohsuke.args4j.Option; abstract class RevWalkTextBuiltin extends TextBuiltin { RevWalk walk; 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 de3df806d8..43b292e39c 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 @@ -59,10 +59,10 @@ import org.eclipse.jgit.lib.IndexDiff.StageState; import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.pgm.internal.CLIText; +import org.eclipse.jgit.pgm.opt.UntrackedFilesHandler; import org.kohsuke.args4j.Argument; import org.kohsuke.args4j.Option; import org.kohsuke.args4j.spi.RestOfArgumentsHandler; -import org.eclipse.jgit.pgm.opt.UntrackedFilesHandler; /** * Status command @@ -70,8 +70,6 @@ import org.eclipse.jgit.pgm.opt.UntrackedFilesHandler; @Command(usage = "usage_Status", common = true) class Status extends TextBuiltin { - protected final String lineFormat = CLIText.get().lineFormat; - protected final String statusFileListFormat = CLIText.get().statusFileListFormat; protected final String statusFileListFormatWithPrefix = CLIText.get().statusFileListFormatWithPrefix; 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 c4d95481f1..52b6d190dd 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 @@ -64,8 +64,8 @@ import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jgit.errors.ConfigInvalidException; import org.eclipse.jgit.lfs.server.LargeFileRepository; import org.eclipse.jgit.lfs.server.LfsProtocolServlet; -import org.eclipse.jgit.lfs.server.fs.FileLfsServlet; import org.eclipse.jgit.lfs.server.fs.FileLfsRepository; +import org.eclipse.jgit.lfs.server.fs.FileLfsServlet; import org.eclipse.jgit.lfs.server.s3.S3Config; import org.eclipse.jgit.lfs.server.s3.S3Repository; import org.eclipse.jgit.pgm.Command; @@ -238,7 +238,7 @@ class LfsStore extends TextBuiltin { case S3: readAWSKeys(); checkOptions(); - S3Config config = new S3Config(region.toString(), bucket, + S3Config config = new S3Config(region, bucket, storageClass.toString(), accessKey, secretKey, expirationSeconds, disableSslVerify); repository = new S3Repository(config); diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/AbstractTreeIteratorHandler.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/AbstractTreeIteratorHandler.java index 6b8a61d4d1..8f56bda5f0 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/AbstractTreeIteratorHandler.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/AbstractTreeIteratorHandler.java @@ -48,12 +48,6 @@ import java.io.File; import java.io.IOException; import java.text.MessageFormat; -import org.kohsuke.args4j.CmdLineException; -import org.kohsuke.args4j.CmdLineParser; -import org.kohsuke.args4j.OptionDef; -import org.kohsuke.args4j.spi.OptionHandler; -import org.kohsuke.args4j.spi.Parameters; -import org.kohsuke.args4j.spi.Setter; import org.eclipse.jgit.dircache.DirCache; import org.eclipse.jgit.dircache.DirCacheIterator; import org.eclipse.jgit.errors.IncorrectObjectTypeException; @@ -66,6 +60,12 @@ import org.eclipse.jgit.treewalk.CanonicalTreeParser; import org.eclipse.jgit.treewalk.FileTreeIterator; import org.eclipse.jgit.treewalk.WorkingTreeOptions; import org.eclipse.jgit.util.FS; +import org.kohsuke.args4j.CmdLineException; +import org.kohsuke.args4j.CmdLineParser; +import org.kohsuke.args4j.OptionDef; +import org.kohsuke.args4j.spi.OptionHandler; +import org.kohsuke.args4j.spi.Parameters; +import org.kohsuke.args4j.spi.Setter; /** * Custom argument handler {@link AbstractTreeIterator} from string values. diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/ObjectIdHandler.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/ObjectIdHandler.java index 364809d835..75ca554efb 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/ObjectIdHandler.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/ObjectIdHandler.java @@ -47,14 +47,14 @@ package org.eclipse.jgit.pgm.opt; import java.io.IOException; import java.text.MessageFormat; +import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.pgm.internal.CLIText; import org.kohsuke.args4j.CmdLineException; import org.kohsuke.args4j.CmdLineParser; import org.kohsuke.args4j.OptionDef; import org.kohsuke.args4j.spi.OptionHandler; import org.kohsuke.args4j.spi.Parameters; import org.kohsuke.args4j.spi.Setter; -import org.eclipse.jgit.lib.ObjectId; -import org.eclipse.jgit.pgm.internal.CLIText; /** * Custom argument handler {@link ObjectId} from string values. 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 122cce7dea..e468023448 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 @@ -46,6 +46,10 @@ package org.eclipse.jgit.pgm.opt; import java.util.ArrayList; import java.util.List; +import org.eclipse.jgit.pgm.internal.CLIText; +import org.eclipse.jgit.treewalk.filter.PathFilter; +import org.eclipse.jgit.treewalk.filter.PathFilterGroup; +import org.eclipse.jgit.treewalk.filter.TreeFilter; import org.kohsuke.args4j.CmdLineException; import org.kohsuke.args4j.CmdLineParser; import org.kohsuke.args4j.Option; @@ -53,10 +57,6 @@ import org.kohsuke.args4j.OptionDef; import org.kohsuke.args4j.spi.OptionHandler; import org.kohsuke.args4j.spi.Parameters; import org.kohsuke.args4j.spi.Setter; -import org.eclipse.jgit.pgm.internal.CLIText; -import org.eclipse.jgit.treewalk.filter.PathFilter; -import org.eclipse.jgit.treewalk.filter.PathFilterGroup; -import org.eclipse.jgit.treewalk.filter.TreeFilter; /** * Create a {@link TreeFilter} to patch math names. diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/RefSpecHandler.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/RefSpecHandler.java index dae0c47642..f50c7aded7 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/RefSpecHandler.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/RefSpecHandler.java @@ -43,14 +43,14 @@ package org.eclipse.jgit.pgm.opt; +import org.eclipse.jgit.pgm.internal.CLIText; +import org.eclipse.jgit.transport.RefSpec; import org.kohsuke.args4j.CmdLineException; import org.kohsuke.args4j.CmdLineParser; import org.kohsuke.args4j.OptionDef; import org.kohsuke.args4j.spi.OptionHandler; import org.kohsuke.args4j.spi.Parameters; import org.kohsuke.args4j.spi.Setter; -import org.eclipse.jgit.pgm.internal.CLIText; -import org.eclipse.jgit.transport.RefSpec; /** * Custom argument handler {@link RefSpec} from string values. diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/RevCommitHandler.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/RevCommitHandler.java index 9ae56e4eaf..7661774f5d 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/RevCommitHandler.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/RevCommitHandler.java @@ -47,18 +47,18 @@ package org.eclipse.jgit.pgm.opt; import java.io.IOException; import java.text.MessageFormat; -import org.kohsuke.args4j.CmdLineException; -import org.kohsuke.args4j.CmdLineParser; -import org.kohsuke.args4j.OptionDef; -import org.kohsuke.args4j.spi.OptionHandler; -import org.kohsuke.args4j.spi.Parameters; -import org.kohsuke.args4j.spi.Setter; import org.eclipse.jgit.errors.IncorrectObjectTypeException; import org.eclipse.jgit.errors.MissingObjectException; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.pgm.internal.CLIText; import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevFlag; +import org.kohsuke.args4j.CmdLineException; +import org.kohsuke.args4j.CmdLineParser; +import org.kohsuke.args4j.OptionDef; +import org.kohsuke.args4j.spi.OptionHandler; +import org.kohsuke.args4j.spi.Parameters; +import org.kohsuke.args4j.spi.Setter; /** * Custom argument handler {@link RevCommit} from string values. diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/RevTreeHandler.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/RevTreeHandler.java index e2879e076a..9f1d21ec4b 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/RevTreeHandler.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/RevTreeHandler.java @@ -47,17 +47,17 @@ package org.eclipse.jgit.pgm.opt; import java.io.IOException; import java.text.MessageFormat; +import org.eclipse.jgit.errors.IncorrectObjectTypeException; +import org.eclipse.jgit.errors.MissingObjectException; +import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.pgm.internal.CLIText; +import org.eclipse.jgit.revwalk.RevTree; import org.kohsuke.args4j.CmdLineException; import org.kohsuke.args4j.CmdLineParser; import org.kohsuke.args4j.OptionDef; import org.kohsuke.args4j.spi.OptionHandler; import org.kohsuke.args4j.spi.Parameters; import org.kohsuke.args4j.spi.Setter; -import org.eclipse.jgit.errors.IncorrectObjectTypeException; -import org.eclipse.jgit.errors.MissingObjectException; -import org.eclipse.jgit.lib.ObjectId; -import org.eclipse.jgit.pgm.internal.CLIText; -import org.eclipse.jgit.revwalk.RevTree; /** * Custom argument handler {@link RevTree} from string values. diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/SubcommandHandler.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/SubcommandHandler.java index 96f3ed0afa..311597e6bb 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/SubcommandHandler.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/opt/SubcommandHandler.java @@ -45,16 +45,16 @@ package org.eclipse.jgit.pgm.opt; import java.text.MessageFormat; +import org.eclipse.jgit.pgm.CommandCatalog; +import org.eclipse.jgit.pgm.CommandRef; +import org.eclipse.jgit.pgm.TextBuiltin; +import org.eclipse.jgit.pgm.internal.CLIText; import org.kohsuke.args4j.CmdLineException; import org.kohsuke.args4j.CmdLineParser; import org.kohsuke.args4j.OptionDef; import org.kohsuke.args4j.spi.OptionHandler; import org.kohsuke.args4j.spi.Parameters; import org.kohsuke.args4j.spi.Setter; -import org.eclipse.jgit.pgm.CommandCatalog; -import org.eclipse.jgit.pgm.CommandRef; -import org.eclipse.jgit.pgm.TextBuiltin; -import org.eclipse.jgit.pgm.internal.CLIText; /** * Custom Argument handler for jgit command selection. diff --git a/org.eclipse.jgit.test/.classpath b/org.eclipse.jgit.test/.classpath index 8b81bf5b03..84b5052a6c 100644 --- a/org.eclipse.jgit.test/.classpath +++ b/org.eclipse.jgit.test/.classpath @@ -4,7 +4,7 @@ <classpathentry kind="src" path="src"/> <classpathentry kind="src" path="tst-rsrc"/> <classpathentry kind="src" path="exttst"/> - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> <classpathentry kind="output" path="bin"/> </classpath> 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 87210fb160..10c29d5576 100644 --- a/org.eclipse.jgit.test/.settings/org.eclipse.jdt.core.prefs +++ b/org.eclipse.jgit.test/.settings/org.eclipse.jdt.core.prefs @@ -7,9 +7,9 @@ org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nul org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.7 +org.eclipse.jdt.core.compiler.compliance=1.8 org.eclipse.jdt.core.compiler.debug.lineNumber=generate org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.debug.sourceFile=generate @@ -112,7 +112,7 @@ org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=error -org.eclipse.jdt.core.compiler.source=1.7 +org.eclipse.jdt.core.compiler.source=1.8 org.eclipse.jdt.core.formatter.align_type_members_on_columns=false org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 diff --git a/org.eclipse.jgit.test/BUCK b/org.eclipse.jgit.test/BUCK index 3df3336b4e..5b7be89b1e 100644 --- a/org.eclipse.jgit.test/BUCK +++ b/org.eclipse.jgit.test/BUCK @@ -60,6 +60,7 @@ for src in TESTS: ':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', @@ -67,7 +68,6 @@ for src in TESTS: '//lib:slf4j-api', '//lib:slf4j-simple', ] + DEPS.get(src, []), - source_under_test = ['//org.eclipse.jgit:jgit'], vm_args = ['-Xmx256m', '-Dfile.encoding=UTF-8'], ) diff --git a/org.eclipse.jgit.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.test/META-INF/MANIFEST.MF index 1dcd97b789..f48cae0b80 100644 --- a/org.eclipse.jgit.test/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.test/META-INF/MANIFEST.MF @@ -2,57 +2,58 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Bundle-SymbolicName: org.eclipse.jgit.test -Bundle-Version: 4.5.3.qualifier +Bundle-Version: 4.6.2.qualifier Bundle-Localization: plugin Bundle-Vendor: %provider_name Bundle-ActivationPolicy: lazy -Bundle-RequiredExecutionEnvironment: JavaSE-1.7 -Import-Package: com.googlecode.javaewah;version="[0.7.9,0.8.0)", - org.eclipse.jgit.api;version="[4.5.3,4.6.0)", - org.eclipse.jgit.api.errors;version="[4.5.3,4.6.0)", - org.eclipse.jgit.attributes;version="[4.5.3,4.6.0)", - org.eclipse.jgit.awtui;version="[4.5.3,4.6.0)", - org.eclipse.jgit.blame;version="[4.5.3,4.6.0)", - org.eclipse.jgit.diff;version="[4.5.3,4.6.0)", - org.eclipse.jgit.dircache;version="[4.5.3,4.6.0)", - org.eclipse.jgit.errors;version="[4.5.3,4.6.0)", - org.eclipse.jgit.events;version="[4.5.3,4.6.0)", - org.eclipse.jgit.fnmatch;version="[4.5.3,4.6.0)", - org.eclipse.jgit.gitrepo;version="[4.5.3,4.6.0)", - org.eclipse.jgit.hooks;version="[4.5.3,4.6.0)", - org.eclipse.jgit.ignore;version="[4.5.3,4.6.0)", - org.eclipse.jgit.ignore.internal;version="[4.5.3,4.6.0)", - org.eclipse.jgit.internal;version="[4.5.3,4.6.0)", - org.eclipse.jgit.internal.storage.dfs;version="[4.5.3,4.6.0)", - org.eclipse.jgit.internal.storage.file;version="[4.5.3,4.6.0)", - org.eclipse.jgit.internal.storage.pack;version="[4.5.3,4.6.0)", - org.eclipse.jgit.internal.storage.reftree;version="[4.5.3,4.6.0)", - org.eclipse.jgit.junit;version="[4.5.3,4.6.0)", - org.eclipse.jgit.lib;version="[4.5.3,4.6.0)", - org.eclipse.jgit.merge;version="[4.5.3,4.6.0)", - org.eclipse.jgit.nls;version="[4.5.3,4.6.0)", - org.eclipse.jgit.notes;version="[4.5.3,4.6.0)", - org.eclipse.jgit.patch;version="[4.5.3,4.6.0)", - org.eclipse.jgit.pgm;version="[4.5.3,4.6.0)", - org.eclipse.jgit.pgm.internal;version="[4.5.3,4.6.0)", - org.eclipse.jgit.revplot;version="[4.5.3,4.6.0)", - org.eclipse.jgit.revwalk;version="[4.5.3,4.6.0)", - org.eclipse.jgit.revwalk.filter;version="[4.5.3,4.6.0)", - org.eclipse.jgit.storage.file;version="[4.5.3,4.6.0)", - org.eclipse.jgit.storage.pack;version="[4.5.3,4.6.0)", - org.eclipse.jgit.submodule;version="[4.5.3,4.6.0)", - org.eclipse.jgit.transport;version="[4.5.3,4.6.0)", - org.eclipse.jgit.transport.http;version="[4.5.3,4.6.0)", - org.eclipse.jgit.transport.resolver;version="[4.5.3,4.6.0)", - org.eclipse.jgit.treewalk;version="[4.5.3,4.6.0)", - org.eclipse.jgit.treewalk.filter;version="[4.5.3,4.6.0)", - org.eclipse.jgit.util;version="[4.5.3,4.6.0)", - org.eclipse.jgit.util.io;version="[4.5.3,4.6.0)", - org.hamcrest;version="[1.1.0,2.0.0)", +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.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)", org.junit.runner;version="[4.4.0,5.0.0)", org.junit.runners;version="[4.11.0,5.0.0)", org.slf4j;version="[1.7.2,2.0.0)" -Require-Bundle: org.hamcrest.core;bundle-version="[1.1.0,2.0.0)" +Require-Bundle: org.hamcrest.core;bundle-version="[1.1.0,2.0.0)", + org.hamcrest.library;bundle-version="[1.1.0,2.0.0)" diff --git a/org.eclipse.jgit.test/org.eclipse.jgit.core--All-External-Tests (Java 6).launch b/org.eclipse.jgit.test/org.eclipse.jgit.core--All-External-Tests (Java 6).launch deleted file mode 100644 index db13a84315..0000000000 --- a/org.eclipse.jgit.test/org.eclipse.jgit.core--All-External-Tests (Java 6).launch +++ /dev/null @@ -1,21 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<launchConfiguration type="org.eclipse.jdt.junit.launchconfig"> -<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS"> -<listEntry value="/org.eclipse.jgit.test/exttst"/> -</listAttribute> -<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES"> -<listEntry value="2"/> -</listAttribute> -<booleanAttribute key="org.eclipse.debug.core.appendEnvironmentVariables" value="true"/> -<listAttribute key="org.eclipse.debug.ui.favoriteGroups"> -<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/> -<listEntry value="org.eclipse.debug.ui.launchGroup.run"/> -</listAttribute> -<stringAttribute key="org.eclipse.jdt.junit.CONTAINER" value="=org.eclipse.jgit.test/exttst"/> -<booleanAttribute key="org.eclipse.jdt.junit.KEEPRUNNING_ATTR" value="false"/> -<stringAttribute key="org.eclipse.jdt.junit.TESTNAME" value=""/> -<stringAttribute key="org.eclipse.jdt.junit.TEST_KIND" value="org.eclipse.jdt.junit.loader.junit4"/> -<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/> -<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value=""/> -<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="org.eclipse.jgit.test"/> -</launchConfiguration> diff --git a/org.eclipse.jgit.test/org.eclipse.jgit.core--All-External-Tests.launch b/org.eclipse.jgit.test/org.eclipse.jgit.core--All-External-Tests.launch deleted file mode 100644 index 2adb02c875..0000000000 --- a/org.eclipse.jgit.test/org.eclipse.jgit.core--All-External-Tests.launch +++ /dev/null @@ -1,20 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<launchConfiguration type="org.eclipse.jdt.junit.launchconfig"> -<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS"> -<listEntry value="/org.eclipse.jgit.test/exttst"/> -</listAttribute> -<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES"> -<listEntry value="2"/> -</listAttribute> -<booleanAttribute key="org.eclipse.debug.core.appendEnvironmentVariables" value="true"/> -<listAttribute key="org.eclipse.debug.ui.favoriteGroups"> -<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/> -<listEntry value="org.eclipse.debug.ui.launchGroup.run"/> -</listAttribute> -<stringAttribute key="org.eclipse.jdt.junit.CONTAINER" value="=org.eclipse.jgit.test/exttst"/> -<booleanAttribute key="org.eclipse.jdt.junit.KEEPRUNNING_ATTR" value="false"/> -<stringAttribute key="org.eclipse.jdt.junit.TESTNAME" value=""/> -<stringAttribute key="org.eclipse.jdt.junit.TEST_KIND" value="org.eclipse.jdt.junit.loader.junit4"/> -<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value=""/> -<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="org.eclipse.jgit.test"/> -</launchConfiguration> diff --git a/org.eclipse.jgit.test/org.eclipse.jgit.core--All-Tests (Java 6).launch b/org.eclipse.jgit.test/org.eclipse.jgit.core--All-Tests (Java 6).launch deleted file mode 100644 index f253d592f4..0000000000 --- a/org.eclipse.jgit.test/org.eclipse.jgit.core--All-Tests (Java 6).launch +++ /dev/null @@ -1,22 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<launchConfiguration type="org.eclipse.jdt.junit.launchconfig"> -<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS"> -<listEntry value="/org.eclipse.jgit.test/tst"/> -</listAttribute> -<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES"> -<listEntry value="2"/> -</listAttribute> -<booleanAttribute key="org.eclipse.debug.core.appendEnvironmentVariables" value="true"/> -<listAttribute key="org.eclipse.debug.ui.favoriteGroups"> -<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/> -<listEntry value="org.eclipse.debug.ui.launchGroup.run"/> -</listAttribute> -<stringAttribute key="org.eclipse.jdt.junit.CONTAINER" value="=org.eclipse.jgit.test/tst"/> -<booleanAttribute key="org.eclipse.jdt.junit.KEEPRUNNING_ATTR" value="false"/> -<stringAttribute key="org.eclipse.jdt.junit.TESTNAME" value=""/> -<stringAttribute key="org.eclipse.jdt.junit.TEST_KIND" value="org.eclipse.jdt.junit.loader.junit4"/> -<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/> -<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value=""/> -<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="org.eclipse.jgit.test"/> -<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx256m"/> -</launchConfiguration> diff --git a/org.eclipse.jgit.test/org.eclipse.jgit.core--All-Tests (Java 7) (de).launch b/org.eclipse.jgit.test/org.eclipse.jgit.core--All-Tests (Java 7) (de).launch deleted file mode 100644 index 86446f987a..0000000000 --- a/org.eclipse.jgit.test/org.eclipse.jgit.core--All-Tests (Java 7) (de).launch +++ /dev/null @@ -1,30 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<launchConfiguration type="org.eclipse.jdt.junit.launchconfig"> -<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS"> -<listEntry value="/org.eclipse.jgit.test/tst"/> -</listAttribute> -<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES"> -<listEntry value="2"/> -</listAttribute> -<booleanAttribute key="org.eclipse.debug.core.appendEnvironmentVariables" value="true"/> -<mapAttribute key="org.eclipse.debug.core.environmentVariables"> -<mapEntry key="LANG" value="de_DE.UTF-8"/> -</mapAttribute> -<listAttribute key="org.eclipse.debug.ui.favoriteGroups"> -<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/> -<listEntry value="org.eclipse.debug.ui.launchGroup.run"/> -</listAttribute> -<stringAttribute key="org.eclipse.jdt.junit.CONTAINER" value="=org.eclipse.jgit.test/tst"/> -<booleanAttribute key="org.eclipse.jdt.junit.KEEPRUNNING_ATTR" value="false"/> -<stringAttribute key="org.eclipse.jdt.junit.TESTNAME" value=""/> -<stringAttribute key="org.eclipse.jdt.junit.TEST_KIND" value="org.eclipse.jdt.junit.loader.junit4"/> -<listAttribute key="org.eclipse.jdt.launching.CLASSPATH"> -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry containerPath="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6" path="1" type="4"/> "/> -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry id="org.eclipse.jdt.launching.classpathentry.defaultClasspath"> <memento exportedEntriesOnly="false" project="org.eclipse.jgit.test"/> </runtimeClasspathEntry> "/> -</listAttribute> -<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/> -<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/> -<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value=""/> -<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="org.eclipse.jgit.test"/> -<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx256m"/> -</launchConfiguration> diff --git a/org.eclipse.jgit.test/org.eclipse.jgit.core--All-Tests (Java 7).launch b/org.eclipse.jgit.test/org.eclipse.jgit.core--All-Tests (Java 7).launch deleted file mode 100644 index a83fabb75e..0000000000 --- a/org.eclipse.jgit.test/org.eclipse.jgit.core--All-Tests (Java 7).launch +++ /dev/null @@ -1,27 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<launchConfiguration type="org.eclipse.jdt.junit.launchconfig"> -<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS"> -<listEntry value="/org.eclipse.jgit.test/tst"/> -</listAttribute> -<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES"> -<listEntry value="2"/> -</listAttribute> -<booleanAttribute key="org.eclipse.debug.core.appendEnvironmentVariables" value="true"/> -<listAttribute key="org.eclipse.debug.ui.favoriteGroups"> -<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/> -<listEntry value="org.eclipse.debug.ui.launchGroup.run"/> -</listAttribute> -<stringAttribute key="org.eclipse.jdt.junit.CONTAINER" value="=org.eclipse.jgit.test/tst"/> -<booleanAttribute key="org.eclipse.jdt.junit.KEEPRUNNING_ATTR" value="false"/> -<stringAttribute key="org.eclipse.jdt.junit.TESTNAME" value=""/> -<stringAttribute key="org.eclipse.jdt.junit.TEST_KIND" value="org.eclipse.jdt.junit.loader.junit4"/> -<listAttribute key="org.eclipse.jdt.launching.CLASSPATH"> -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry containerPath="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6" path="1" type="4"/> "/> -<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry id="org.eclipse.jdt.launching.classpathentry.defaultClasspath"> <memento exportedEntriesOnly="false" project="org.eclipse.jgit.test"/> </runtimeClasspathEntry> "/> -</listAttribute> -<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/> -<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/> -<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value=""/> -<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="org.eclipse.jgit.test"/> -<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx256m"/> -</launchConfiguration> diff --git a/org.eclipse.jgit.test/pom.xml b/org.eclipse.jgit.test/pom.xml index d9e9e20177..1aff2898b2 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.5.3-SNAPSHOT</version> + <version>4.6.2-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.test</artifactId> diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/indexdiff/filerepo.txt b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/indexdiff/filerepo.txt new file mode 100644 index 0000000000..3255efb8c6 --- /dev/null +++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/indexdiff/filerepo.txt @@ -0,0 +1,30 @@ +blob +mark :1 +data 10 +äéü.txt +blob +mark :2 +data 8 +test.txt +blob +mark :3 +data 5 +Test + +blob +mark :4 +data 7 +äéü + +reset refs/heads/master +commit refs/heads/master +mark :5 +author A U Thor <author@example.com> 1450727513 +0100 +committer A U Thor <author@example.com> 1450727513 +0100 +data 26 +Initial commit with links +M 120000 :1 testfolder/aeu.txt +M 120000 :2 testfolder/link.txt +M 100644 :3 testfolder/test.txt +M 100644 :4 testfolder/äéü.txt + 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 42601aaa9f..5ad73f17b0 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 @@ -57,12 +57,21 @@ import java.util.Set; import org.eclipse.jgit.api.errors.FilterFailedException; import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.api.errors.NoFilepatternException; +import org.eclipse.jgit.attributes.FilterCommandRegistry; import org.eclipse.jgit.dircache.DirCache; import org.eclipse.jgit.dircache.DirCacheBuilder; import org.eclipse.jgit.dircache.DirCacheEntry; import org.eclipse.jgit.junit.JGitTestUtil; import org.eclipse.jgit.junit.RepositoryTestCase; -import org.eclipse.jgit.lib.*; +import org.eclipse.jgit.lfs.CleanFilter; +import org.eclipse.jgit.lfs.SmudgeFilter; +import org.eclipse.jgit.lib.ConfigConstants; +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.Repository; +import org.eclipse.jgit.lib.StoredConfig; import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.storage.file.FileRepositoryBuilder; import org.eclipse.jgit.treewalk.TreeWalk; @@ -70,8 +79,23 @@ import org.eclipse.jgit.treewalk.WorkingTreeOptions; import org.eclipse.jgit.util.FS; import org.eclipse.jgit.util.FileUtils; import org.junit.Test; +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 AddCommandTest extends RepositoryTestCase { + @DataPoints + public static boolean[] sleepBeforeAddOptions = { true, false }; + + + @Override + public void setUp() throws Exception { + CleanFilter.register(); + SmudgeFilter.register(); + super.setUp(); + } @Test public void testAddNothing() throws GitAPIException { @@ -110,8 +134,7 @@ public class AddCommandTest extends RepositoryTestCase { } @Test - public void testCleanFilter() throws IOException, - GitAPIException { + public void testCleanFilter() throws IOException, GitAPIException { writeTrashFile(".gitattributes", "*.txt filter=tstFilter"); writeTrashFile("src/a.tmp", "foo"); // Caution: we need a trailing '\n' since sed on mac always appends @@ -134,6 +157,128 @@ public class AddCommandTest extends RepositoryTestCase { } } + @Theory + public void testBuiltinFilters(boolean sleepBeforeAdd) + throws IOException, + GitAPIException, InterruptedException { + writeTrashFile(".gitattributes", "*.txt filter=lfs"); + writeTrashFile("src/a.tmp", "foo"); + // Caution: we need a trailing '\n' since sed on mac always appends + // linefeeds if missing + File script = writeTempFile("sed s/o/e/g"); + File f = writeTrashFile("src/a.txt", "foo\n"); + + try (Git git = new Git(db)) { + if (!sleepBeforeAdd) { + fsTick(f); + } + git.add().addFilepattern(".gitattributes").call(); + StoredConfig config = git.getRepository().getConfig(); + config.setString("filter", "lfs", "clean", + "sh " + slashify(script.getPath())); + config.setString("filter", "lfs", "smudge", + "sh " + slashify(script.getPath())); + config.setBoolean("filter", "lfs", "useJGitBuiltin", true); + config.save(); + + if (!sleepBeforeAdd) { + fsTick(f); + } + git.add().addFilepattern("src/a.txt").addFilepattern("src/a.tmp") + .addFilepattern(".gitattributes").call(); + + assertEquals( + "[.gitattributes, mode:100644, content:*.txt filter=lfs][src/a.tmp, mode:100644, content:foo][src/a.txt, mode:100644, content:version https://git-lfs.github.com/spec/v1\noid sha256:b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c\nsize 4\n]", + indexState(CONTENT)); + + RevCommit c1 = git.commit().setMessage("c1").call(); + assertTrue(git.status().call().isClean()); + f = writeTrashFile("src/a.txt", "foobar\n"); + if (!sleepBeforeAdd) { + fsTick(f); + } + git.add().addFilepattern("src/a.txt").call(); + git.commit().setMessage("c2").call(); + assertTrue(git.status().call().isClean()); + assertEquals( + "[.gitattributes, mode:100644, content:*.txt filter=lfs][src/a.tmp, mode:100644, content:foo][src/a.txt, mode:100644, content:version https://git-lfs.github.com/spec/v1\noid sha256:aec070645fe53ee3b3763059376134f058cc337247c978add178b6ccdfb0019f\nsize 7\n]", + indexState(CONTENT)); + assertEquals("foobar\n", read("src/a.txt")); + git.checkout().setName(c1.getName()).call(); + assertEquals( + "[.gitattributes, mode:100644, content:*.txt filter=lfs][src/a.tmp, mode:100644, content:foo][src/a.txt, mode:100644, content:version https://git-lfs.github.com/spec/v1\noid sha256:b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c\nsize 4\n]", + indexState(CONTENT)); + assertEquals( + "foo\n", read("src/a.txt")); + } + } + + @Theory + public void testBuiltinCleanFilter(boolean sleepBeforeAdd) + throws IOException, GitAPIException, InterruptedException { + writeTrashFile(".gitattributes", "*.txt filter=lfs"); + writeTrashFile("src/a.tmp", "foo"); + // Caution: we need a trailing '\n' since sed on mac always appends + // linefeeds if missing + File script = writeTempFile("sed s/o/e/g"); + File f = writeTrashFile("src/a.txt", "foo\n"); + + // unregister the smudge filter. Only clean filter should be builtin + FilterCommandRegistry.unregister( + org.eclipse.jgit.lib.Constants.BUILTIN_FILTER_PREFIX + + "lfs/smudge"); + + try (Git git = new Git(db)) { + if (!sleepBeforeAdd) { + fsTick(f); + } + git.add().addFilepattern(".gitattributes").call(); + StoredConfig config = git.getRepository().getConfig(); + config.setString("filter", "lfs", "clean", + "sh " + slashify(script.getPath())); + config.setString("filter", "lfs", "smudge", + "sh " + slashify(script.getPath())); + config.setBoolean("filter", "lfs", "useJGitBuiltin", true); + config.save(); + + if (!sleepBeforeAdd) { + fsTick(f); + } + git.add().addFilepattern("src/a.txt").addFilepattern("src/a.tmp") + .addFilepattern(".gitattributes").call(); + + assertEquals( + "[.gitattributes, mode:100644, content:*.txt filter=lfs][src/a.tmp, mode:100644, content:foo][src/a.txt, mode:100644, content:version https://git-lfs.github.com/spec/v1\noid sha256:b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c\nsize 4\n]", + indexState(CONTENT)); + + RevCommit c1 = git.commit().setMessage("c1").call(); + assertTrue(git.status().call().isClean()); + f = writeTrashFile("src/a.txt", "foobar\n"); + if (!sleepBeforeAdd) { + fsTick(f); + } + git.add().addFilepattern("src/a.txt").call(); + git.commit().setMessage("c2").call(); + assertTrue(git.status().call().isClean()); + assertEquals( + "[.gitattributes, mode:100644, content:*.txt filter=lfs][src/a.tmp, mode:100644, content:foo][src/a.txt, mode:100644, content:version https://git-lfs.github.com/spec/v1\noid sha256:aec070645fe53ee3b3763059376134f058cc337247c978add178b6ccdfb0019f\nsize 7\n]", + indexState(CONTENT)); + assertEquals("foobar\n", read("src/a.txt")); + git.checkout().setName(c1.getName()).call(); + assertEquals( + "[.gitattributes, mode:100644, content:*.txt filter=lfs][src/a.tmp, mode:100644, content:foo][src/a.txt, mode:100644, content:version https://git-lfs.github.com/spec/v1\noid sha256:b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c\nsize 4\n]", + indexState(CONTENT)); + // due to lfs clean filter but dummy smudge filter we expect strange + // content. The smudge filter converts from real content to pointer + // file content (starting with "version ") but the smudge filter + // replaces 'o' by 'e' which results in a text starting with + // "versien " + assertEquals( + "versien https://git-lfs.github.cem/spec/v1\neid sha256:b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c\nsize 4\n", + read("src/a.txt")); + } + } + @Test public void testAttributesWithTreeWalkFilter() throws IOException, GitAPIException { diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CheckoutCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CheckoutCommandTest.java index 0bb6610a24..3c196724a9 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CheckoutCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CheckoutCommandTest.java @@ -74,6 +74,8 @@ import org.eclipse.jgit.dircache.DirCache; import org.eclipse.jgit.dircache.DirCacheEntry; import org.eclipse.jgit.junit.JGitTestUtil; import org.eclipse.jgit.junit.RepositoryTestCase; +import org.eclipse.jgit.lfs.CleanFilter; +import org.eclipse.jgit.lfs.SmudgeFilter; import org.eclipse.jgit.lib.ConfigConstants; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.Ref; @@ -87,6 +89,7 @@ import org.eclipse.jgit.transport.RefSpec; import org.eclipse.jgit.transport.RemoteConfig; import org.eclipse.jgit.transport.URIish; import org.eclipse.jgit.util.FileUtils; +import org.eclipse.jgit.util.SystemReader; import org.junit.Before; import org.junit.Test; @@ -100,6 +103,8 @@ public class CheckoutCommandTest extends RepositoryTestCase { @Override @Before public void setUp() throws Exception { + CleanFilter.register(); + SmudgeFilter.register(); super.setUp(); git = new Git(db); // commit something @@ -563,11 +568,11 @@ public class CheckoutCommandTest extends RepositoryTestCase { public void testSmudgeFilter_modifyExisting() throws IOException, GitAPIException { File script = writeTempFile("sed s/o/e/g"); StoredConfig config = git.getRepository().getConfig(); - config.setString("filter", "tstFilter", "smudge", + config.setString("filter", "lfs", "smudge", "sh " + slashify(script.getPath())); config.save(); - writeTrashFile(".gitattributes", "*.txt filter=tstFilter"); + writeTrashFile(".gitattributes", "*.txt filter=lfs"); git.add().addFilepattern(".gitattributes").call(); git.commit().setMessage("add filter").call(); @@ -589,7 +594,7 @@ public class CheckoutCommandTest extends RepositoryTestCase { git.checkout().setName(content2.getName()).call(); assertEquals( - "[.gitattributes, mode:100644, content:*.txt filter=tstFilter][Test.txt, mode:100644, content:Some change][src/a.tmp, mode:100644, content:foo][src/a.txt, mode:100644, content:foo\n]", + "[.gitattributes, mode:100644, content:*.txt filter=lfs][Test.txt, mode:100644, content:Some change][src/a.tmp, mode:100644, content:foo][src/a.txt, mode:100644, content:foo\n]", indexState(CONTENT)); assertEquals(Sets.of("src/a.txt"), git.status().call().getModified()); assertEquals("foo", read("src/a.tmp")); @@ -601,7 +606,7 @@ public class CheckoutCommandTest extends RepositoryTestCase { throws IOException, GitAPIException { File script = writeTempFile("sed s/o/e/g"); StoredConfig config = git.getRepository().getConfig(); - config.setString("filter", "tstFilter", "smudge", + config.setString("filter", "lfs", "smudge", "sh " + slashify(script.getPath())); config.save(); @@ -609,7 +614,7 @@ public class CheckoutCommandTest extends RepositoryTestCase { git.add().addFilepattern("foo").call(); RevCommit initial = git.commit().setMessage("initial").call(); - writeTrashFile(".gitattributes", "*.txt filter=tstFilter"); + writeTrashFile(".gitattributes", "*.txt filter=lfs"); git.add().addFilepattern(".gitattributes").call(); git.commit().setMessage("add filter").call(); @@ -625,7 +630,7 @@ public class CheckoutCommandTest extends RepositoryTestCase { git.checkout().setName(content.getName()).call(); assertEquals( - "[.gitattributes, mode:100644, content:*.txt filter=tstFilter][Test.txt, mode:100644, content:Some change][foo, mode:100644, content:foo][src/a.tmp, mode:100644, content:foo][src/a.txt, mode:100644, content:foo\n]", + "[.gitattributes, mode:100644, content:*.txt filter=lfs][Test.txt, mode:100644, content:Some change][foo, mode:100644, content:foo][src/a.tmp, mode:100644, content:foo][src/a.txt, mode:100644, content:foo\n]", indexState(CONTENT)); assertEquals("foo", read("src/a.tmp")); assertEquals("fee\n", read("src/a.txt")); @@ -636,7 +641,7 @@ public class CheckoutCommandTest extends RepositoryTestCase { throws IOException, GitAPIException { File script = writeTempFile("sed s/o/e/g"); StoredConfig config = git.getRepository().getConfig(); - config.setString("filter", "tstFilter", "smudge", + config.setString("filter", "lfs", "smudge", "sh " + slashify(script.getPath())); config.save(); @@ -644,7 +649,7 @@ public class CheckoutCommandTest extends RepositoryTestCase { git.add().addFilepattern("foo").call(); git.commit().setMessage("initial").call(); - writeTrashFile(".gitattributes", "*.txt filter=tstFilter"); + writeTrashFile(".gitattributes", "*.txt filter=lfs"); git.add().addFilepattern(".gitattributes").call(); git.commit().setMessage("add filter").call(); @@ -661,7 +666,7 @@ public class CheckoutCommandTest extends RepositoryTestCase { .call(); assertEquals( - "[.gitattributes, mode:100644, content:*.txt filter=tstFilter][Test.txt, mode:100644, content:Some change][foo, mode:100644, content:foo][src/a.tmp, mode:100644, content:foo][src/a.txt, mode:100644, content:foo\n]", + "[.gitattributes, mode:100644, content:*.txt filter=lfs][Test.txt, mode:100644, content:Some change][foo, mode:100644, content:foo][src/a.tmp, mode:100644, content:foo][src/a.txt, mode:100644, content:foo\n]", indexState(CONTENT)); assertEquals("foo", read("src/a.tmp")); assertEquals("fee\n", read("src/a.txt")); @@ -672,7 +677,7 @@ public class CheckoutCommandTest extends RepositoryTestCase { throws IOException, GitAPIException { File script = writeTempFile("sed s/o/e/g"); StoredConfig config = git.getRepository().getConfig(); - config.setString("filter", "tstFilter", "smudge", + config.setString("filter", "lfs", "smudge", "sh " + slashify(script.getPath())); config.save(); @@ -680,7 +685,7 @@ public class CheckoutCommandTest extends RepositoryTestCase { git.add().addFilepattern("foo").call(); git.commit().setMessage("initial").call(); - writeTrashFile(".gitattributes", "*.txt filter=tstFilter"); + writeTrashFile(".gitattributes", "*.txt filter=lfs"); git.add().addFilepattern(".gitattributes").call(); git.commit().setMessage("add filter").call(); @@ -696,7 +701,7 @@ public class CheckoutCommandTest extends RepositoryTestCase { git.checkout().addPath("src/a.txt").call(); assertEquals( - "[.gitattributes, mode:100644, content:*.txt filter=tstFilter][Test.txt, mode:100644, content:Some change][foo, mode:100644, content:foo][src/a.tmp, mode:100644, content:foo][src/a.txt, mode:100644, content:foo\n]", + "[.gitattributes, mode:100644, content:*.txt filter=lfs][Test.txt, mode:100644, content:Some change][foo, mode:100644, content:foo][src/a.tmp, mode:100644, content:foo][src/a.txt, mode:100644, content:foo\n]", indexState(CONTENT)); assertEquals("foo", read("src/a.tmp")); assertEquals("fee\n", read("src/a.txt")); @@ -707,7 +712,7 @@ public class CheckoutCommandTest extends RepositoryTestCase { throws IOException, GitAPIException { File script = writeTempFile("sed s/o/e/g"); StoredConfig config = git.getRepository().getConfig(); - config.setString("filter", "tstFilter", "smudge", + config.setString("filter", "lfs", "smudge", "sh " + slashify(script.getPath())); config.save(); @@ -715,7 +720,7 @@ public class CheckoutCommandTest extends RepositoryTestCase { git.add().addFilepattern("foo").call(); git.commit().setMessage("initial").call(); - writeTrashFile(".gitattributes", "*.txt filter=tstFilter"); + writeTrashFile(".gitattributes", "*.txt filter=lfs"); git.add().addFilepattern(".gitattributes").call(); git.commit().setMessage("add filter").call(); @@ -732,7 +737,7 @@ public class CheckoutCommandTest extends RepositoryTestCase { .setStartPoint(content).addPath("src/a.txt").call(); assertEquals( - "[.gitattributes, mode:100644, content:*.txt filter=tstFilter][Test.txt, mode:100644, content:Some change][foo, mode:100644, content:foo][src/a.tmp, mode:100644, content:foo][src/a.txt, mode:100644, content:foo\n]", + "[.gitattributes, mode:100644, content:*.txt filter=lfs][Test.txt, mode:100644, content:Some change][foo, mode:100644, content:foo][src/a.tmp, mode:100644, content:foo][src/a.txt, mode:100644, content:foo\n]", indexState(CONTENT)); assertEquals("foo", read("src/a.tmp")); assertEquals("fee\n", read("src/a.txt")); @@ -745,12 +750,13 @@ public class CheckoutCommandTest extends RepositoryTestCase { try (Git git2 = new Git(db)) { StoredConfig config = git.getRepository().getConfig(); - config.setString("filter", "tstFilter", "smudge", + config.setString("filter", "lfs", "smudge", "sh " + slashify(smudge_filter.getPath())); - config.setString("filter", "tstFilter", "clean", + config.setString("filter", "lfs", "clean", "sh " + slashify(clean_filter.getPath())); + config.setBoolean("filter", "lfs", "useJGitBuiltin", true); config.save(); - writeTrashFile(".gitattributes", "filterTest.txt filter=tstFilter"); + writeTrashFile(".gitattributes", "filterTest.txt filter=lfs"); git2.add().addFilepattern(".gitattributes").call(); git2.commit().setMessage("add attributes").call(); @@ -758,7 +764,7 @@ public class CheckoutCommandTest extends RepositoryTestCase { git2.add().addFilepattern("filterTest.txt").call(); RevCommit one = git2.commit().setMessage("add filterText.txt").call(); assertEquals( - "[.gitattributes, mode:100644, content:filterTest.txt filter=tstFilter][Test.txt, mode:100644, content:Some change][filterTest.txt, mode:100644, content:hello world, @version\n]", + "[.gitattributes, mode:100644, content:filterTest.txt filter=lfs][Test.txt, mode:100644, content:Some change][filterTest.txt, mode:100644, content:version https://git-lfs.github.com/spec/v1\noid sha256:7bd5d32e5c494354aa4c2473a1306d0ce7b52cc3bffeb342c03cd517ef8cf8da\nsize 16\n]", indexState(CONTENT)); fsTick(writeTrashFile("filterTest.txt", "bon giorno world, V1\n")); @@ -767,25 +773,57 @@ public class CheckoutCommandTest extends RepositoryTestCase { assertTrue(git2.status().call().isClean()); assertEquals( - "[.gitattributes, mode:100644, content:filterTest.txt filter=tstFilter][Test.txt, mode:100644, content:Some change][filterTest.txt, mode:100644, content:bon giorno world, @version\n]", + "[.gitattributes, mode:100644, content:filterTest.txt filter=lfs][Test.txt, mode:100644, content:Some change][filterTest.txt, mode:100644, content:version https://git-lfs.github.com/spec/v1\noid sha256:087148cccf53b0049c56475c1595113c9da4b638997c3489af8ac7108d51ef13\nsize 21\n]", indexState(CONTENT)); git2.checkout().setName(one.getName()).call(); assertTrue(git2.status().call().isClean()); assertEquals( - "[.gitattributes, mode:100644, content:filterTest.txt filter=tstFilter][Test.txt, mode:100644, content:Some change][filterTest.txt, mode:100644, content:hello world, @version\n]", + "[.gitattributes, mode:100644, content:filterTest.txt filter=lfs][Test.txt, mode:100644, content:Some change][filterTest.txt, mode:100644, content:version https://git-lfs.github.com/spec/v1\noid sha256:7bd5d32e5c494354aa4c2473a1306d0ce7b52cc3bffeb342c03cd517ef8cf8da\nsize 16\n]", indexState(CONTENT)); assertEquals("hello world, V1\n", read("filterTest.txt")); git2.checkout().setName(two.getName()).call(); assertTrue(git2.status().call().isClean()); assertEquals( - "[.gitattributes, mode:100644, content:filterTest.txt filter=tstFilter][Test.txt, mode:100644, content:Some change][filterTest.txt, mode:100644, content:bon giorno world, @version\n]", + "[.gitattributes, mode:100644, content:filterTest.txt filter=lfs][Test.txt, mode:100644, content:Some change][filterTest.txt, mode:100644, content:version https://git-lfs.github.com/spec/v1\noid sha256:087148cccf53b0049c56475c1595113c9da4b638997c3489af8ac7108d51ef13\nsize 21\n]", indexState(CONTENT)); assertEquals("bon giorno world, V1\n", read("filterTest.txt")); } } + @Test + public void testNonDeletableFilesOnWindows() + throws GitAPIException, IOException { + // Only on windows a FileInputStream blocks us from deleting a file + org.junit.Assume.assumeTrue(SystemReader.getInstance().isWindows()); + writeTrashFile("toBeModified.txt", "a"); + writeTrashFile("toBeDeleted.txt", "a"); + git.add().addFilepattern(".").call(); + RevCommit addFiles = git.commit().setMessage("add more files").call(); + + git.rm().setCached(false).addFilepattern("Test.txt") + .addFilepattern("toBeDeleted.txt").call(); + writeTrashFile("toBeModified.txt", "b"); + writeTrashFile("toBeCreated.txt", "a"); + git.add().addFilepattern(".").call(); + RevCommit crudCommit = git.commit().setMessage("delete, modify, add") + .call(); + git.checkout().setName(addFiles.getName()).call(); + try ( FileInputStream fis=new FileInputStream(new File(db.getWorkTree(), "Test.txt")) ) { + CheckoutCommand coCommand = git.checkout(); + coCommand.setName(crudCommit.getName()).call(); + CheckoutResult result = coCommand.getResult(); + assertEquals(Status.NONDELETED, result.getStatus()); + assertEquals("[Test.txt, toBeDeleted.txt]", + result.getRemovedList().toString()); + assertEquals("[toBeCreated.txt, toBeModified.txt]", + result.getModifiedList().toString()); + assertEquals("[Test.txt]", result.getUndeletedList().toString()); + assertTrue(result.getConflictList().isEmpty()); + } + } + private File writeTempFile(String body) throws IOException { File f = File.createTempFile("AddCommandTest_", ""); JGitTestUtil.write(f, body); 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 68f5dd1e0d..0e1cf02c86 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 @@ -42,10 +42,10 @@ */ package org.eclipse.jgit.api; +import static org.eclipse.jgit.lib.Constants.DOT_GIT_MODULES; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import static org.eclipse.jgit.lib.Constants.DOT_GIT_MODULES; import java.io.File; import java.util.Set; 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 8a07118f84..473dce1136 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 @@ -43,10 +43,10 @@ package org.eclipse.jgit.api; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; -import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.fail; import java.io.File; diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/DiffCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/DiffCommandTest.java index 4f5b50dcc1..43c3a8cf92 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/DiffCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/DiffCommandTest.java @@ -95,7 +95,7 @@ public class DiffCommandTest extends RepositoryTestCase { + "\\ No newline at end of file\n" + "+folder change\n" + "\\ No newline at end of file\n"; - assertEquals(expected.toString(), actual); + assertEquals(expected, actual); } } @@ -130,7 +130,7 @@ public class DiffCommandTest extends RepositoryTestCase { + "@@ -0,0 +1 @@\n" + "+folder\n" + "\\ No newline at end of file\n"; - assertEquals(expected.toString(), actual); + assertEquals(expected, actual); } } @@ -179,7 +179,7 @@ public class DiffCommandTest extends RepositoryTestCase { + "\\ No newline at end of file\n" + "+folder change\n" + "\\ No newline at end of file\n"; - assertEquals(expected.toString(), actual); + assertEquals(expected, actual); } } @@ -201,7 +201,7 @@ public class DiffCommandTest extends RepositoryTestCase { + "+++ new/test.txt\n" + "@@ -1 +1 @@\n" + "-test\n" + "\\ No newline at end of file\n" + "+test change\n" + "\\ No newline at end of file\n"; - assertEquals(expected.toString(), actual); + assertEquals(expected, actual); } } @@ -223,7 +223,7 @@ public class DiffCommandTest extends RepositoryTestCase { + "index f55b5c9..c5ec8fd 100644\n" + "--- a/test.txt\n" + "+++ b/test.txt\n" + "@@ -4,3 +4,3 @@\n" + " 3\n" + "-4\n" + "+4a\n" + " 5\n"; - assertEquals(expected.toString(), actual); + assertEquals(expected, actual); } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/EolStreamTypeUtilTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/EolStreamTypeUtilTest.java index 8ca1b3175d..2ee77a010a 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/EolStreamTypeUtilTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/EolStreamTypeUtilTest.java @@ -42,8 +42,12 @@ package org.eclipse.jgit.api; +import static org.eclipse.jgit.lib.CoreConfig.EolStreamType.AUTO_CRLF; +import static org.eclipse.jgit.lib.CoreConfig.EolStreamType.AUTO_LF; +import static org.eclipse.jgit.lib.CoreConfig.EolStreamType.DIRECT; +import static org.eclipse.jgit.lib.CoreConfig.EolStreamType.TEXT_CRLF; +import static org.eclipse.jgit.lib.CoreConfig.EolStreamType.TEXT_LF; import static org.junit.Assert.assertArrayEquals; -import static org.eclipse.jgit.lib.CoreConfig.EolStreamType.*; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/NotesCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/NotesCommandTest.java index 6ddf89c4a4..9d15699963 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/NotesCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/NotesCommandTest.java @@ -43,6 +43,7 @@ package org.eclipse.jgit.api; import static org.junit.Assert.assertEquals; + import java.util.List; import org.eclipse.jgit.junit.RepositoryTestCase; 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 638a163757..b4234dcba3 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 @@ -45,6 +45,7 @@ package org.eclipse.jgit.diff; import static org.junit.Assert.assertEquals; +import java.io.BufferedOutputStream; import java.io.ByteArrayOutputStream; import java.io.File; @@ -65,7 +66,6 @@ import org.eclipse.jgit.treewalk.filter.PathFilter; import org.eclipse.jgit.util.FileUtils; import org.eclipse.jgit.util.RawParseUtils; import org.eclipse.jgit.util.io.DisabledOutputStream; -import org.eclipse.jgit.util.io.SafeBufferedOutputStream; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -381,7 +381,7 @@ public class DiffFormatterTest extends RepositoryTestCase { write(new File(folder, "folder.txt"), "folder"); try (Git git = new Git(db); ByteArrayOutputStream os = new ByteArrayOutputStream(); - DiffFormatter dfmt = new DiffFormatter(new SafeBufferedOutputStream(os))) { + DiffFormatter dfmt = new DiffFormatter(new BufferedOutputStream(os))) { git.add().addFilepattern(".").call(); git.commit().setMessage("Initial commit").call(); write(new File(folder, "folder.txt"), "folder change"); @@ -414,7 +414,7 @@ public class DiffFormatterTest extends RepositoryTestCase { write(new File(folder, "folder.txt"), "folder"); try (Git git = new Git(db); ByteArrayOutputStream os = new ByteArrayOutputStream(); - DiffFormatter dfmt = new DiffFormatter(new SafeBufferedOutputStream(os))) { + DiffFormatter dfmt = new DiffFormatter(new BufferedOutputStream(os))) { git.add().addFilepattern(".").call(); RevCommit commit = git.commit().setMessage("Initial commit").call(); write(new File(folder, "folder.txt"), "folder change"); @@ -446,7 +446,7 @@ public class DiffFormatterTest extends RepositoryTestCase { write(new File(folder, "folder.txt"), "folder"); try (Git git = new Git(db); ByteArrayOutputStream os = new ByteArrayOutputStream(); - DiffFormatter dfmt = new DiffFormatter(new SafeBufferedOutputStream(os));) { + DiffFormatter dfmt = new DiffFormatter(new BufferedOutputStream(os));) { git.add().addFilepattern(".").call(); RevCommit commit = git.commit().setMessage("Initial commit").call(); write(new File(folder, "folder.txt"), "folder change"); @@ -473,7 +473,7 @@ public class DiffFormatterTest extends RepositoryTestCase { @Test public void testDiffNullToNull() throws Exception { try (ByteArrayOutputStream os = new ByteArrayOutputStream(); - DiffFormatter dfmt = new DiffFormatter(new SafeBufferedOutputStream(os))) { + DiffFormatter dfmt = new DiffFormatter(new BufferedOutputStream(os))) { dfmt.setRepository(db); dfmt.format((AnyObjectId) null, null); dfmt.flush(); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/fnmatch/FileNameMatcherTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/fnmatch/FileNameMatcherTest.java index 1db6c80304..ba785911b1 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/fnmatch/FileNameMatcherTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/fnmatch/FileNameMatcherTest.java @@ -69,7 +69,7 @@ public class FileNameMatcherTest { final boolean appendCanMatchExpected) throws InvalidPatternException { final FileNameMatcher matcher = new FileNameMatcher(pattern, - new Character(excludedCharacter)); + Character.valueOf(excludedCharacter)); matcher.append(input); assertEquals(matchExpected, matcher.isMatch()); assertEquals(appendCanMatchExpected, matcher.canAppendMatch()); 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 30b3df1c0d..b1138f04cd 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 @@ -42,8 +42,8 @@ */ package org.eclipse.jgit.gitrepo; -import static org.junit.Assert.assertTrue; import static java.nio.charset.StandardCharsets.UTF_8; +import static org.junit.Assert.assertTrue; import java.io.ByteArrayInputStream; import java.util.HashSet; diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/indexdiff/IndexDiffWithSymlinkTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/indexdiff/IndexDiffWithSymlinkTest.java new file mode 100644 index 0000000000..4f3b601d3c --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/indexdiff/IndexDiffWithSymlinkTest.java @@ -0,0 +1,234 @@ +/* + * Copyright (C) 2015 Thomas Wolf <thomas.wolf@paranor.ch> + * + * 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.indexdiff; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.junit.Assume.assumeTrue; + +import java.io.BufferedOutputStream; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Collections; + +import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase; +import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.lib.IndexDiff; +import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.storage.file.FileRepositoryBuilder; +import org.eclipse.jgit.treewalk.FileTreeIterator; +import org.eclipse.jgit.treewalk.WorkingTreeIterator; +import org.eclipse.jgit.treewalk.filter.PathFilterGroup; +import org.eclipse.jgit.util.FS; +import org.eclipse.jgit.util.SystemReader; +import org.junit.Before; +import org.junit.Test; + +/** + * MacOS-only test for dealing with symlinks in IndexDiff. Recreates using cgit + * a test repository prepared with git 2.2.1 on MacOS 10.7.5 containing some + * symlinks. Examines a symlink pointing to a file named "äéü.txt" (should be + * encoded as UTF-8 NFC), changes it through Java, examines it again to verify + * it's been changed to UTF-8 NFD, and finally calculates an IndexDiff. + */ +public class IndexDiffWithSymlinkTest extends LocalDiskRepositoryTestCase { + + private static final String FILEREPO = "filerepo"; + + private static final String TESTFOLDER = "testfolder"; + + private static final String TESTTARGET = "äéü.txt"; + + private static final String TESTLINK = "aeu.txt"; + + private static final byte[] NFC = // "äéü.txt" in NFC + { -61, -92, -61, -87, -61, -68, 46, 116, 120, 116 }; + + private static final byte[] NFD = // "äéü.txt" in NFD + { 97, -52, -120, 101, -52, -127, 117, -52, -120, 46, 116, 120, 116 }; + + private File testRepoDir; + + @Override + @Before + public void setUp() throws Exception { + assumeTrue(SystemReader.getInstance().isMacOS() + && FS.DETECTED.supportsSymlinks()); + super.setUp(); + File testDir = createTempDirectory(this.getClass().getSimpleName()); + InputStream in = this.getClass().getClassLoader().getResourceAsStream( + this.getClass().getPackage().getName().replace('.', '/') + '/' + + FILEREPO + ".txt"); + assertNotNull("Test repo file not found", in); + try { + testRepoDir = restoreGitRepo(in, testDir, FILEREPO); + } finally { + in.close(); + } + } + + private File restoreGitRepo(InputStream in, File testDir, String name) + throws Exception { + File exportedTestRepo = new File(testDir, name + ".txt"); + copy(in, exportedTestRepo); + // Use CGit to restore + File restoreScript = new File(testDir, name + ".sh"); + try (OutputStream out = new BufferedOutputStream( + new FileOutputStream(restoreScript)); + Writer writer = new OutputStreamWriter(out, + StandardCharsets.UTF_8)) { + writer.write("echo `which git` 1>&2\n"); + writer.write("echo `git --version` 1>&2\n"); + writer.write("git init " + name + " && \\\n"); + writer.write("cd ./" + name + " && \\\n"); + writer.write("git fast-import < ../" + name + ".txt && \\\n"); + writer.write("git checkout -f\n"); + } + String[] cmd = { "/bin/sh", "./" + name + ".sh" }; + int exitCode; + String stdErr; + Process process = Runtime.getRuntime().exec(cmd, null, testDir); + try (InputStream stdOutStream = process.getInputStream(); + InputStream stdErrStream = process.getErrorStream(); + OutputStream stdInStream = process.getOutputStream()) { + readStream(stdOutStream); + stdErr = readStream(stdErrStream); + process.waitFor(); + exitCode = process.exitValue(); + } + if (exitCode != 0) { + fail("cgit repo restore returned " + exitCode + '\n' + stdErr); + } + return new File(new File(testDir, name), Constants.DOT_GIT); + } + + private void copy(InputStream from, File to) throws IOException { + try (OutputStream out = new FileOutputStream(to)) { + byte[] buffer = new byte[4096]; + int n; + while ((n = from.read(buffer)) > 0) { + out.write(buffer, 0, n); + } + } + } + + private String readStream(InputStream stream) throws IOException { + try (BufferedReader in = new BufferedReader( + new InputStreamReader(stream))) { + StringBuilder out = new StringBuilder(); + String line; + while ((line = in.readLine()) != null) { + out.append(line).append('\n'); + } + return out.toString(); + } + } + + @Test + public void testSymlinkWithEncodingDifference() throws Exception { + try (Repository testRepo = FileRepositoryBuilder.create(testRepoDir)) { + File workingTree = testRepo.getWorkTree(); + File symLink = new File(new File(workingTree, TESTFOLDER), + TESTLINK); + // Read the symlink as it was created by cgit + Path linkTarget = Files.readSymbolicLink(symLink.toPath()); + assertEquals("Unexpected link target", TESTTARGET, + linkTarget.toString()); + byte[] raw = rawPath(linkTarget); + if (raw != null) { + assertArrayEquals("Expected an NFC link target", NFC, raw); + } + // Now re-create that symlink through Java + assertTrue("Could not delete symlink", symLink.delete()); + Files.createSymbolicLink(symLink.toPath(), Paths.get(TESTTARGET)); + // Read it again + linkTarget = Files.readSymbolicLink(symLink.toPath()); + assertEquals("Unexpected link target", TESTTARGET, + linkTarget.toString()); + raw = rawPath(linkTarget); + if (raw != null) { + assertArrayEquals("Expected an NFD link target", NFD, raw); + } + // Do the indexdiff + WorkingTreeIterator iterator = new FileTreeIterator(testRepo); + IndexDiff diff = new IndexDiff(testRepo, Constants.HEAD, iterator); + diff.setFilter(PathFilterGroup.createFromStrings( + Collections.singleton(TESTFOLDER + '/' + TESTLINK))); + diff.diff(); + // We're testing that this does NOT throw "EOFException: Short read + // of block." The diff will not report any modified files -- the + // link modification is not visible to JGit, which always works with + // the Java internal NFC encoding. CGit does report the link as an + // unstaged modification here, though. + } + } + + private byte[] rawPath(Path p) { + try { + Method method = p.getClass().getDeclaredMethod("asByteArray"); + if (method != null) { + method.setAccessible(true); + return (byte[]) method.invoke(p); + } + } catch (NoSuchMethodException | IllegalAccessException + | IllegalArgumentException | InvocationTargetException e) { + // Ignore and fall through. + } + return null; + } +} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsBlockCacheConfigTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsBlockCacheConfigTest.java new file mode 100644 index 0000000000..e612061abf --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsBlockCacheConfigTest.java @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2016, Philipp Marx <philippmarx@gmx.de> and + * other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v1.0 which accompanies this + * distribution, is reproduced below, and is available at + * http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +package org.eclipse.jgit.internal.storage.dfs; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; + +import org.eclipse.jgit.internal.JGitText; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +public class DfsBlockCacheConfigTest { + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Test + public void blockSizeNotPowerOfTwoExpectsException() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage(is(JGitText.get().blockSizeNotPowerOf2)); + + new DfsBlockCacheConfig().setBlockSize(1000); + } + + @Test + @SuppressWarnings("boxing") + public void negativeBlockSizeIsConvertedToDefault() { + DfsBlockCacheConfig config = new DfsBlockCacheConfig(); + config.setBlockSize(-1); + + assertThat(config.getBlockSize(), is(512)); + } + + @Test + @SuppressWarnings("boxing") + public void tooSmallBlockSizeIsConvertedToDefault() { + DfsBlockCacheConfig config = new DfsBlockCacheConfig(); + config.setBlockSize(10); + + assertThat(config.getBlockSize(), is(512)); + } + + @Test + @SuppressWarnings("boxing") + public void validBlockSize() { + DfsBlockCacheConfig config = new DfsBlockCacheConfig(); + config.setBlockSize(65536); + + assertThat(config.getBlockSize(), is(65536)); + } +} 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 987540399b..ece8f67368 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 @@ -50,6 +50,7 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import java.io.BufferedOutputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; @@ -60,9 +61,6 @@ import java.util.Collection; import java.util.List; import org.eclipse.jgit.errors.AmbiguousObjectException; -import org.eclipse.jgit.internal.storage.file.FileRepository; -import org.eclipse.jgit.internal.storage.file.PackIndexWriter; -import org.eclipse.jgit.internal.storage.file.PackIndexWriterV2; import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase; import org.eclipse.jgit.junit.TestRepository; import org.eclipse.jgit.lib.AbbreviatedObjectId; @@ -72,7 +70,6 @@ import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.revwalk.RevBlob; import org.eclipse.jgit.transport.PackedObjectInfo; import org.eclipse.jgit.util.FileUtils; -import org.eclipse.jgit.util.io.SafeBufferedOutputStream; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -183,13 +180,10 @@ public class AbbreviationTest extends LocalDiskRepositoryTestCase { File idxFile = new File(packDir, packName + ".idx"); File packFile = new File(packDir, packName + ".pack"); FileUtils.mkdir(packDir, true); - OutputStream dst = new SafeBufferedOutputStream(new FileOutputStream( - idxFile)); - try { + try (OutputStream dst = new BufferedOutputStream( + new FileOutputStream(idxFile))) { PackIndexWriter writer = new PackIndexWriterV2(dst); writer.write(objects, new byte[OBJECT_ID_LENGTH]); - } finally { - dst.close(); } new FileOutputStream(packFile).close(); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/AutoGcTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/AutoGcTest.java new file mode 100644 index 0000000000..56994a63b2 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/AutoGcTest.java @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2016, Matthias Sohn <matthias.sohn@sap.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.internal.storage.file; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.eclipse.jgit.lib.ConfigConstants; +import org.eclipse.jgit.storage.file.FileBasedConfig; +import org.eclipse.jgit.test.resources.SampleDataRepositoryTestCase; +import org.junit.Test; + +public class AutoGcTest extends GcTestCase { + + @Test + public void testNotTooManyLooseObjects() { + assertFalse("should not find too many loose objects", + gc.tooManyLooseObjects()); + } + + @Test + public void testTooManyLooseObjects() throws Exception { + FileBasedConfig c = repo.getConfig(); + c.setInt(ConfigConstants.CONFIG_GC_SECTION, null, + ConfigConstants.CONFIG_KEY_AUTO, 255); + c.save(); + commitChain(10, 50); + assertTrue("should find too many loose objects", + gc.tooManyLooseObjects()); + } + + @Test + public void testNotTooManyPacks() { + assertFalse("should not find too many packs", gc.tooManyPacks()); + } + + @Test + public void testTooManyPacks() throws Exception { + FileBasedConfig c = repo.getConfig(); + c.setInt(ConfigConstants.CONFIG_GC_SECTION, null, + ConfigConstants.CONFIG_KEY_AUTOPACKLIMIT, 1); + c.save(); + SampleDataRepositoryTestCase.copyCGitTestPacks(repo); + + assertTrue("should find too many packs", gc.tooManyPacks()); + } +} 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 9d7a4822a3..1d71cb3cff 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 @@ -51,6 +51,7 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotSame; import static org.junit.Assert.fail; +import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; @@ -71,7 +72,6 @@ import org.eclipse.jgit.revwalk.RevObject; import org.eclipse.jgit.revwalk.RevWalk; import org.eclipse.jgit.storage.file.WindowCacheConfig; import org.eclipse.jgit.util.FileUtils; -import org.eclipse.jgit.util.io.SafeBufferedOutputStream; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -235,20 +235,15 @@ public class ConcurrentRepackTest extends RepositoryTestCase { throws IOException { final long begin = files[0].getParentFile().lastModified(); NullProgressMonitor m = NullProgressMonitor.INSTANCE; - OutputStream out; - out = new SafeBufferedOutputStream(new FileOutputStream(files[0])); - try { + try (OutputStream out = new BufferedOutputStream( + new FileOutputStream(files[0]))) { pw.writePack(m, m, out); - } finally { - out.close(); } - out = new SafeBufferedOutputStream(new FileOutputStream(files[1])); - try { + try (OutputStream out = new BufferedOutputStream( + new FileOutputStream(files[1]))) { pw.writeIndex(out); - } finally { - out.close(); } touch(begin, files[0].getParentFile()); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/DescriptionTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/DescriptionTest.java new file mode 100644 index 0000000000..73bd35b19a --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/DescriptionTest.java @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2016, Google Inc. + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.eclipse.jgit.internal.storage.file; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import java.io.File; +import java.io.IOException; + +import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase; +import org.eclipse.jgit.lib.Repository; +import org.junit.Test; + +/** Test managing the gitweb description file. */ +public class DescriptionTest extends LocalDiskRepositoryTestCase { + private static final String UNCONFIGURED = "Unnamed repository; edit this file to name it for gitweb."; + + @Test + public void description() throws IOException { + Repository git = createBareRepository(); + File path = new File(git.getDirectory(), "description"); + assertNull("description", git.getGitwebDescription()); + + String desc = "a test repo\nfor jgit"; + git.setGitwebDescription(desc); + assertEquals(desc + '\n', read(path)); + assertEquals(desc, git.getGitwebDescription()); + + git.setGitwebDescription(null); + assertEquals("", read(path)); + + desc = "foo"; + git.setGitwebDescription(desc); + assertEquals(desc + '\n', read(path)); + assertEquals(desc, git.getGitwebDescription()); + + git.setGitwebDescription(""); + assertEquals("", read(path)); + + git.setGitwebDescription(UNCONFIGURED); + assertEquals(UNCONFIGURED + '\n', read(path)); + assertNull("description", git.getGitwebDescription()); + } +} 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 902416bdff..98a9501766 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 @@ -42,7 +42,6 @@ */ package org.eclipse.jgit.internal.storage.file; -import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import java.io.File; @@ -51,7 +50,6 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; -import org.eclipse.jgit.internal.storage.file.FileSnapshot; import org.eclipse.jgit.util.FileUtils; import org.junit.After; import org.junit.Before; @@ -99,22 +97,6 @@ public class FileSnapshotTest { } /** - * Create a file, wait long enough and verify that it has not been modified. - * 3.5 seconds mean any difference between file system timestamp and system - * clock should be significant. - * - * @throws Exception - */ - @Test - public void testOldFile() throws Exception { - File f1 = createFile("oldfile"); - waitNextSec(f1); - FileSnapshot save = FileSnapshot.save(f1); - Thread.sleep(3500); - assertFalse(save.isModified(f1)); - } - - /** * Create a file, but don't wait long enough for the difference between file * system clock and system clock to be significant. Assume the file may have * been modified. It may have been, but the clock alone cannot determine 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 new file mode 100644 index 0000000000..d9317b89a7 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcOrphanFilesTest.java @@ -0,0 +1,119 @@ +/* + * 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.internal.storage.file; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.IOException; + +import org.junit.Before; +import org.junit.Test; + +public class GcOrphanFilesTest extends GcTestCase { + private final static String PACK = "pack"; + + private final static String BITMAP_File_1 = PACK + "-1.bitmap"; + + private final static String IDX_File_2 = PACK + "-2.idx"; + + private final static String IDX_File_malformed = PACK + "-1234idx"; + + private final static String PACK_File_2 = PACK + "-2.pack"; + + private final static String PACK_File_3 = PACK + "-3.pack"; + + private File packDir; + + @Before + public void setUp() throws Exception { + super.setUp(); + packDir = new File(repo.getObjectsDirectory(), PACK); + } + + @Test + public void bitmapAndIdxDeletedButPackNot() throws Exception { + createFileInPackFolder(BITMAP_File_1); + createFileInPackFolder(IDX_File_2); + createFileInPackFolder(PACK_File_3); + gc.gc(); + assertFalse(new File(packDir, BITMAP_File_1).exists()); + assertFalse(new File(packDir, IDX_File_2).exists()); + assertTrue(new File(packDir, PACK_File_3).exists()); + } + + @Test + public void bitmapDeletedButIdxAndPackNot() throws Exception { + createFileInPackFolder(BITMAP_File_1); + createFileInPackFolder(IDX_File_2); + createFileInPackFolder(PACK_File_2); + createFileInPackFolder(PACK_File_3); + gc.gc(); + assertFalse(new File(packDir, BITMAP_File_1).exists()); + assertTrue(new File(packDir, IDX_File_2).exists()); + assertTrue(new File(packDir, PACK_File_2).exists()); + assertTrue(new File(packDir, PACK_File_3).exists()); + } + + @Test + public void malformedIdxNotDeleted() throws Exception { + createFileInPackFolder(IDX_File_malformed); + gc.gc(); + assertTrue(new File(packDir, IDX_File_malformed).exists()); + } + + private void createFileInPackFolder(String fileName) throws IOException { + if (!packDir.exists() || !packDir.isDirectory()) { + assertTrue(packDir.mkdirs()); + } + assertTrue(new File(packDir, fileName).createNewFile()); + } + + @Test + public void noSuchPackFolder() throws Exception { + assertTrue(packDir.delete()); + gc.gc(); + } +} 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 e463285915..90c115227d 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 @@ -105,6 +105,46 @@ public abstract class GcTestCase extends LocalDiskRepositoryTestCase { return tip; } + /** + * Create a chain of commits of given depth with given number of added files + * per commit. + * <p> + * Each commit contains {@code files} files as its content. The created + * commit chain is referenced from any ref. + * <p> + * A chain will create {@code (2 + files) * depth} objects in Gits object + * database. For each depth level the following objects are created: the + * commit object, the top-level tree object and @code files} blobs for the + * content of the file "a". + * + * @param depth + * the depth of the commit chain. + * @param width + * number of files added per commit + * @return the commit that is the tip of the commit chain + * @throws Exception + */ + protected RevCommit commitChain(int depth, int width) throws Exception { + if (depth <= 0) { + throw new IllegalArgumentException("Chain depth must be > 0"); + } + if (width <= 0) { + throw new IllegalArgumentException("Number of files per commit must be > 0"); + } + CommitBuilder cb = tr.commit(); + RevCommit tip = null; + do { + --depth; + for (int i=0; i < width; i++) { + String id = depth + "-" + i; + cb.add("a" + id, id).message(id); + } + tip = cb.create(); + cb = cb.child(); + } while (depth > 0); + return tip; + } + protected long lastModified(AnyObjectId objectId) throws IOException { return repo.getFS().lastModified( repo.getObjectDatabase().fileFor(objectId)); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/InflatingBitSetTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/InflatingBitSetTest.java index 465c61b845..2124b80ebb 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/InflatingBitSetTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/InflatingBitSetTest.java @@ -46,11 +46,10 @@ package org.eclipse.jgit.internal.storage.file; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import com.googlecode.javaewah.EWAHCompressedBitmap; - -import org.eclipse.jgit.internal.storage.file.InflatingBitSet; import org.junit.Test; +import com.googlecode.javaewah.EWAHCompressedBitmap; + public class InflatingBitSetTest { @Test diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/LockFileTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/LockFileTest.java index f1bc7c8f64..3bfd047783 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/LockFileTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/LockFileTest.java @@ -49,7 +49,6 @@ import static org.junit.Assert.fail; import org.eclipse.jgit.api.Git; import org.eclipse.jgit.api.errors.JGitInternalException; import org.eclipse.jgit.errors.LockFailedException; -import org.eclipse.jgit.internal.storage.file.LockFile; import org.eclipse.jgit.junit.RepositoryTestCase; import org.eclipse.jgit.revwalk.RevCommit; import org.junit.Test; 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 923f283894..87554ae6a4 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 @@ -42,6 +42,11 @@ package org.eclipse.jgit.internal.storage.file; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.FilenameFilter; import java.util.Collection; import java.util.Collections; import java.util.concurrent.Callable; @@ -49,10 +54,13 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; -import org.eclipse.jgit.internal.storage.file.ObjectDirectory; 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.revwalk.RevCommit; +import org.eclipse.jgit.storage.file.FileBasedConfig; +import org.junit.Assume; import org.junit.Test; public class ObjectDirectoryTest extends RepositoryTestCase { @@ -69,6 +77,100 @@ public class ObjectDirectoryTest extends RepositoryTestCase { } } + /** + * Test packfile scanning while a gc is done from the outside (different + * process or different Repository instance). This situation occurs e.g. if + * a gerrit server is serving fetch requests while native git is doing a + * garbage collection. The test shows that when core.trustfolderstat==true + * jgit may miss to detect that a new packfile was created. This situation + * is persistent until a new full rescan of the pack directory is triggered. + * + * The test works with two Repository instances working on the same disk + * location. One (db) for all write operations (creating commits, doing gc) + * and another one (receivingDB) which just reads and which in the end shows + * the bug + * + * @throws Exception + */ + @Test + public void testScanningForPackfiles() throws Exception { + ObjectId unknownID = ObjectId + .fromString("c0ffee09d0b63d694bf49bc1e6847473f42d4a8c"); + GC gc = new GC(db); + gc.setExpireAgeMillis(0); + gc.setPackExpireAgeMillis(0); + + // the default repo db is used to create the objects. The receivingDB + // repo is used to trigger gc's + try (FileRepository receivingDB = new FileRepository( + db.getDirectory())) { + // set trustfolderstat to true. If set to false the test always + // succeeds. + FileBasedConfig cfg = receivingDB.getConfig(); + cfg.setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null, + ConfigConstants.CONFIG_KEY_TRUSTFOLDERSTAT, true); + cfg.save(); + + // setup a repo which has at least one pack file and trigger + // scanning of the packs directory + ObjectId id = commitFile("file.txt", "test", "master").getId(); + gc.gc(); + assertFalse(receivingDB.hasObject(unknownID)); + assertTrue(receivingDB.getObjectDatabase().hasPackedObject(id)); + + // preparations + File packsFolder = new File(receivingDB.getObjectsDirectory(), + "pack"); + // prepare creation of a temporary file in the pack folder. This + // simulates that a native git gc is happening starting to write + // temporary files but has not yet finished + File tmpFile = new File(packsFolder, "1.tmp"); + RevCommit id2 = commitFile("file.txt", "test2", "master"); + // wait until filesystem timer ticks. This raises probability that + // the next statements are executed in the same tick as the + // filesystem timer + fsTick(null); + + // create a Temp file in the packs folder and trigger a rescan of + // the packs folder. This lets receivingDB think it has scanned the + // packs folder at the current fs timestamp t1. The following gc + // will create new files which have the same timestamp t1 but this + // will not update the mtime of the packs folder. Because of that + // JGit will not rescan the packs folder later on and fails to see + // the pack file created during gc. + assertTrue(tmpFile.createNewFile()); + assertFalse(receivingDB.hasObject(unknownID)); + + // trigger a gc. This will create packfiles which have likely the + // same mtime than the packfolder + gc.gc(); + + // To deal with racy-git situations JGit's Filesnapshot class will + // report a file/folder potentially dirty if + // cachedLastReadTime-cachedLastModificationTime < 2500ms. This + // causes JGit to always rescan a file after modification. But: + // this was true only if the difference between current system time + // and cachedLastModification time was less than 2500ms. If the + // modification is more than 2500ms ago we may have reported a + // file/folder to be clean although it has not been rescanned. A + // Bug. To show the bug we sleep for more than 2500ms + Thread.sleep(2600); + + File[] ret = packsFolder.listFiles(new FilenameFilter() { + @Override + public boolean accept(File dir, String name) { + return name.endsWith(".pack"); + } + }); + assertTrue(ret.length == 1); + Assume.assumeTrue(tmpFile.lastModified() == ret[0].lastModified()); + + // all objects are in a new packfile but we will not detect it + assertFalse(receivingDB.hasObject(unknownID)); + assertTrue(receivingDB.hasObject(id2)); + } + } + private Collection<Callable<ObjectId>> blobInsertersForTheSameFanOutDir( final ObjectDirectory dir) { Callable<ObjectId> callable = new Callable<ObjectId>() { 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 ba07d6842f..1c10bb335a 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 @@ -310,6 +310,27 @@ public class PackFileTest extends LocalDiskRepositoryTestCase { } } + @Test + public void testConfigurableStreamFileThreshold() throws Exception { + byte[] data = getRng().nextBytes(300); + RevBlob id = tr.blob(data); + tr.branch("master").commit().add("A", id).create(); + tr.packAndPrune(); + assertTrue("has blob", wc.has(id)); + + ObjectLoader ol = wc.open(id); + ObjectStream in = ol.openStream(); + assertTrue(in instanceof ObjectStream.SmallStream); + assertEquals(300, in.available()); + in.close(); + + wc.setStreamFileThreshold(299); + ol = wc.open(id); + in = ol.openStream(); + assertTrue(in instanceof ObjectStream.Filter); + assertEquals(1, in.available()); + } + private static byte[] clone(int first, byte[] base) { byte[] r = new byte[base.length]; System.arraycopy(base, 1, r, 1, r.length - 1); 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 7eeb0c0eaa..b6aa4bcec2 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 @@ -52,7 +52,6 @@ import java.util.Iterator; import java.util.NoSuchElementException; import org.eclipse.jgit.errors.MissingObjectException; -import org.eclipse.jgit.internal.storage.file.PackIndex; import org.eclipse.jgit.internal.storage.file.PackIndex.MutableEntry; import org.eclipse.jgit.junit.RepositoryTestCase; import org.junit.Test; 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 2126cac97a..a4aa8bcee1 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 @@ -50,8 +50,6 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import org.eclipse.jgit.errors.CorruptObjectException; -import org.eclipse.jgit.internal.storage.file.PackIndex; -import org.eclipse.jgit.internal.storage.file.PackReverseIndex; import org.eclipse.jgit.internal.storage.file.PackIndex.MutableEntry; import org.eclipse.jgit.junit.JGitTestUtil; import org.eclipse.jgit.junit.RepositoryTestCase; 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 3cb4c39c76..2e57952486 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 @@ -43,13 +43,13 @@ package org.eclipse.jgit.internal.storage.file; +import static org.eclipse.jgit.internal.storage.pack.PackWriter.NONE; import static org.eclipse.jgit.lib.Constants.OBJ_BLOB; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import static org.eclipse.jgit.internal.storage.pack.PackWriter.NONE; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -75,8 +75,8 @@ import org.eclipse.jgit.lib.NullProgressMonitor; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectIdSet; import org.eclipse.jgit.lib.ObjectInserter; -import org.eclipse.jgit.lib.Sets; import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.lib.Sets; import org.eclipse.jgit.revwalk.DepthWalk; import org.eclipse.jgit.revwalk.ObjectWalk; import org.eclipse.jgit.revwalk.RevBlob; 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 ef5dfcd8ee..5999acf69c 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 @@ -73,8 +73,8 @@ import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase; import org.eclipse.jgit.junit.TestRepository; import org.eclipse.jgit.lib.AnyObjectId; import org.eclipse.jgit.lib.BatchRefUpdate; -import org.eclipse.jgit.lib.ProgressMonitor; import org.eclipse.jgit.lib.NullProgressMonitor; +import org.eclipse.jgit.lib.ProgressMonitor; import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.Ref.Storage; import org.eclipse.jgit.lib.RefDatabase; diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/T0003_BasicTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/T0003_BasicTest.java index b6ad22bbe5..ae1e531b83 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/T0003_BasicTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/T0003_BasicTest.java @@ -82,9 +82,13 @@ import org.eclipse.jgit.storage.file.FileBasedConfig; import org.eclipse.jgit.storage.file.FileRepositoryBuilder; import org.eclipse.jgit.test.resources.SampleDataRepositoryTestCase; import org.eclipse.jgit.util.FileUtils; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; public class T0003_BasicTest extends SampleDataRepositoryTestCase { + @Rule + public ExpectedException expectedException = ExpectedException.none(); @Test public void test001_Initalize() { @@ -326,6 +330,17 @@ public class T0003_BasicTest extends SampleDataRepositoryTestCase { } @Test + public void test002_CreateBadTree() throws Exception { + // We won't create a tree entry with an empty filename + // + expectedException.expect(IllegalArgumentException.class); + expectedException.expectMessage(JGitText.get().invalidTreeZeroLengthName); + final TreeFormatter formatter = new TreeFormatter(); + formatter.append("", FileMode.TREE, + ObjectId.fromString("4b825dc642cb6eb9a060e54bf8d69288fbee4904")); + } + + @Test public void test006_ReadUglyConfig() throws IOException, ConfigInvalidException { final File cfg = new File(db.getDirectory(), Constants.CONFIG); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/pack/DeltaIndexTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/pack/DeltaIndexTest.java index bb94a370ad..640203dd54 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/pack/DeltaIndexTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/pack/DeltaIndexTest.java @@ -51,9 +51,6 @@ import static org.junit.Assert.assertTrue; import java.io.ByteArrayOutputStream; import java.io.IOException; -import org.eclipse.jgit.internal.storage.pack.BinaryDelta; -import org.eclipse.jgit.internal.storage.pack.DeltaEncoder; -import org.eclipse.jgit.internal.storage.pack.DeltaIndex; import org.eclipse.jgit.junit.JGitTestUtil; import org.eclipse.jgit.junit.TestRng; import org.eclipse.jgit.lib.Constants; diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/pack/GcCommitSelectionTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/pack/GcCommitSelectionTest.java index 49e1f6f3da..20b8c51ee4 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/pack/GcCommitSelectionTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/pack/GcCommitSelectionTest.java @@ -55,8 +55,6 @@ import java.util.Set; import org.eclipse.jgit.internal.storage.file.GcTestCase; import org.eclipse.jgit.internal.storage.file.PackBitmapIndexBuilder; -import org.eclipse.jgit.internal.storage.pack.ObjectToPack; -import org.eclipse.jgit.internal.storage.pack.PackWriterBitmapPreparer; import org.eclipse.jgit.internal.storage.pack.PackWriterBitmapPreparer.BitmapCommit; import org.eclipse.jgit.junit.TestRepository.BranchBuilder; import org.eclipse.jgit.junit.TestRepository.CommitBuilder; diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConstantsEncodingTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConstantsEncodingTest.java index 4db6f6da2e..5c2fddd7dc 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConstantsEncodingTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConstantsEncodingTest.java @@ -48,6 +48,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import java.io.UnsupportedEncodingException; + import org.junit.Test; public class ConstantsEncodingTest { diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/DirCacheCheckoutMaliciousPathTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/DirCacheCheckoutMaliciousPathTest.java index 59a4699bcd..32a1ec96a5 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/DirCacheCheckoutMaliciousPathTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/DirCacheCheckoutMaliciousPathTest.java @@ -366,7 +366,9 @@ public class DirCacheCheckoutMaliciousPathTest extends RepositoryTestCase { insertId = blobId; for (int i = path.length - 1; i >= 0; --i) { TreeFormatter treeFormatter = new TreeFormatter(); - treeFormatter.append(path[i], mode, insertId); + treeFormatter.append(path[i].getBytes(), 0, + path[i].getBytes().length, + mode, insertId, true); insertId = newObjectInserter.insert(treeFormatter); mode = FileMode.TREE; } 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 2198b87aa5..80ece1c26a 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 @@ -50,7 +50,6 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import org.eclipse.jgit.errors.InvalidObjectIdException; - import org.junit.Test; public class ObjectIdTest { diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/MergeMessageFormatterTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/MergeMessageFormatterTest.java index 6c90f7d44b..f2715444e1 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/MergeMessageFormatterTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/MergeMessageFormatterTest.java @@ -50,9 +50,9 @@ import java.util.Arrays; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectIdRef; import org.eclipse.jgit.lib.Ref; -import org.eclipse.jgit.lib.SymbolicRef; import org.eclipse.jgit.lib.Ref.Storage; import org.eclipse.jgit.lib.RefUpdate; +import org.eclipse.jgit.lib.SymbolicRef; import org.eclipse.jgit.test.resources.SampleDataRepositoryTestCase; import org.junit.Before; import org.junit.Test; diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/patch/PatchCcErrorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/patch/PatchCcErrorTest.java index 962e81856b..e4b43172d6 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/patch/PatchCcErrorTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/patch/PatchCcErrorTest.java @@ -44,7 +44,6 @@ package org.eclipse.jgit.patch; import static java.lang.Integer.valueOf; -import static java.lang.Long.valueOf; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/FooterLineTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/FooterLineTest.java index fbd5127116..87c8547812 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/FooterLineTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/FooterLineTest.java @@ -48,6 +48,7 @@ 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 java.io.IOException; import java.util.List; diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/ObjectWalkFilterTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/ObjectWalkFilterTest.java index 55117b78e4..75ac561943 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/ObjectWalkFilterTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/ObjectWalkFilterTest.java @@ -46,22 +46,20 @@ package org.eclipse.jgit.revwalk; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; +import java.io.IOException; +import java.util.Set; import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription; import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository; import org.eclipse.jgit.junit.TestRepository; import org.eclipse.jgit.lib.AnyObjectId; import org.eclipse.jgit.lib.Sets; -import org.eclipse.jgit.revwalk.ObjectWalk; import org.eclipse.jgit.revwalk.filter.MessageRevFilter; import org.eclipse.jgit.revwalk.filter.NotRevFilter; import org.eclipse.jgit.revwalk.filter.ObjectFilter; - -import java.io.IOException; -import java.util.Set; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; public class ObjectWalkFilterTest { private TestRepository<InMemoryRepository> tr; diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkMergeBaseTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkMergeBaseTest.java index b5d4909f39..2451c50f6f 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkMergeBaseTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkMergeBaseTest.java @@ -146,4 +146,29 @@ public class RevWalkMergeBaseTest extends RevWalkTestCase { assertCommit(b, rw.next()); assertNull(rw.next()); } -} + + @Test + public void testInconsistentCommitTimes() throws Exception { + // When commit times are inconsistent (a parent is younger than a child) + // make sure that not both, parent and child, are reported as merge + // base. In the following repo the merge base between C,D should be B. + // But when A is younger than B the MergeBaseGenerator used to generate + // A before it detected that B is also a merge base. + // + // +---C + // / / + // A---B---D + + final RevCommit a = commit(2); + final RevCommit b = commit(-1, a); + final RevCommit c = commit(2, b, a); + final RevCommit d = commit(1, b); + + rw.setRevFilter(RevFilter.MERGE_BASE); + markStart(d); + markStart(c); + assertCommit(b, rw.next()); + assertNull(rw.next()); + } + +}
\ No newline at end of file diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/test/resources/SampleDataRepositoryTestCase.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/test/resources/SampleDataRepositoryTestCase.java index 3a3b3d8d8f..a57ef40b62 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/test/resources/SampleDataRepositoryTestCase.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/test/resources/SampleDataRepositoryTestCase.java @@ -47,7 +47,9 @@ package org.eclipse.jgit.test.resources; import java.io.File; +import java.io.IOException; +import org.eclipse.jgit.internal.storage.file.FileRepository; import org.eclipse.jgit.junit.JGitTestUtil; import org.eclipse.jgit.junit.RepositoryTestCase; @@ -57,7 +59,17 @@ public abstract class SampleDataRepositoryTestCase extends RepositoryTestCase { @Override public void setUp() throws Exception { super.setUp(); + copyCGitTestPacks(db); + } + /** + * Copy C Git generated pack files into given repository for testing + * + * @param repo + * test repository to receive packfile copies + * @throws IOException + */ + public static void copyCGitTestPacks(FileRepository repo) throws IOException { final String[] packs = { "pack-34be9032ac282b11fa9babdc2b2a93ca996c9c2f", "pack-df2982f284bbabb6bdb59ee3fcc6eb0983e20371", @@ -67,13 +79,14 @@ public abstract class SampleDataRepositoryTestCase extends RepositoryTestCase { "pack-e6d07037cbcf13376308a0a995d1fa48f8f76aaa", "pack-3280af9c07ee18a87705ef50b0cc4cd20266cf12" }; - final File packDir = new File(db.getObjectDatabase().getDirectory(), "pack"); + final File packDir = new File(repo.getObjectDatabase().getDirectory(), + "pack"); for (String n : packs) { JGitTestUtil.copyTestResource(n + ".pack", new File(packDir, n + ".pack")); JGitTestUtil.copyTestResource(n + ".idx", new File(packDir, n + ".idx")); } JGitTestUtil.copyTestResource("packed-refs", - new File(db.getDirectory(), "packed-refs")); + new File(repo.getDirectory(), "packed-refs")); } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/SideBandOutputStreamTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/SideBandOutputStreamTest.java index d2c3a0b92f..4571619603 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/SideBandOutputStreamTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/SideBandOutputStreamTest.java @@ -44,7 +44,6 @@ package org.eclipse.jgit.transport; import static java.lang.Integer.valueOf; -import static java.lang.Long.valueOf; import static org.eclipse.jgit.transport.SideBandOutputStream.CH_DATA; import static org.eclipse.jgit.transport.SideBandOutputStream.CH_ERROR; import static org.eclipse.jgit.transport.SideBandOutputStream.CH_PROGRESS; 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 ac2bfd12f9..cc5870ebfe 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 @@ -576,7 +576,7 @@ public class WalkEncryptionTest { .forName("javax.crypto.JceSecurity") .getDeclaredField("isRestricted"); isRestricted.setAccessible(true); - isRestricted.set(null, new Boolean(restrictedOn)); + isRestricted.set(null, Boolean.valueOf(restrictedOn)); } catch (Throwable e) { logger.info( "Could not setup JCE security policy restrictions."); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FilterCommandsTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FilterCommandsTest.java new file mode 100644 index 0000000000..0d31811257 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/FilterCommandsTest.java @@ -0,0 +1,251 @@ +/* + * Copyright (C) 2016, Christian Halstrick <christian.halstrick@sap.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.assertEquals; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.api.errors.GitAPIException; +import org.eclipse.jgit.attributes.FilterCommand; +import org.eclipse.jgit.attributes.FilterCommandFactory; +import org.eclipse.jgit.attributes.FilterCommandRegistry; +import org.eclipse.jgit.junit.RepositoryTestCase; +import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.lib.RefUpdate; +import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.lib.StoredConfig; +import org.eclipse.jgit.revwalk.RevCommit; +import org.junit.Before; +import org.junit.Test; + +public class FilterCommandsTest extends RepositoryTestCase { + private Git git; + + RevCommit initialCommit; + + RevCommit secondCommit; + + class TestCommandFactory implements FilterCommandFactory { + private int prefix; + + public TestCommandFactory(int prefix) { + this.prefix = prefix; + } + + @Override + public FilterCommand create(Repository repo, InputStream in, + final OutputStream out) { + FilterCommand cmd = new FilterCommand(in, out) { + + @Override + public int run() throws IOException { + int b = in.read(); + if (b == -1) { + return b; + } + out.write(prefix); + out.write(b); + return 1; + } + }; + return cmd; + } + } + + @Override + @Before + public void setUp() throws Exception { + super.setUp(); + git = new Git(db); + // commit something + writeTrashFile("Test.txt", "Hello world"); + git.add().addFilepattern("Test.txt").call(); + initialCommit = git.commit().setMessage("Initial commit").call(); + + // create a master branch and switch to it + git.branchCreate().setName("test").call(); + RefUpdate rup = db.updateRef(Constants.HEAD); + rup.link("refs/heads/test"); + + // commit something on the test branch + writeTrashFile("Test.txt", "Some change"); + git.add().addFilepattern("Test.txt").call(); + secondCommit = git.commit().setMessage("Second commit").call(); + } + + @Test + public void testBuiltinCleanFilter() + throws IOException, GitAPIException { + String builtinCommandName = "jgit://builtin/test/clean"; + FilterCommandRegistry.register(builtinCommandName, + new TestCommandFactory('c')); + StoredConfig config = git.getRepository().getConfig(); + config.setString("filter", "test", "clean", builtinCommandName); + config.save(); + + writeTrashFile(".gitattributes", "*.txt filter=test"); + git.add().addFilepattern(".gitattributes").call(); + git.commit().setMessage("add filter").call(); + + writeTrashFile("Test.txt", "Hello again"); + git.add().addFilepattern("Test.txt").call(); + assertEquals( + "[.gitattributes, mode:100644, content:*.txt filter=test][Test.txt, mode:100644, content:cHceclclcoc cacgcacicn]", + indexState(CONTENT)); + + writeTrashFile("Test.bin", "Hello again"); + git.add().addFilepattern("Test.bin").call(); + assertEquals( + "[.gitattributes, mode:100644, content:*.txt filter=test][Test.bin, mode:100644, content:Hello again][Test.txt, mode:100644, content:cHceclclcoc cacgcacicn]", + indexState(CONTENT)); + + config.setString("filter", "test", "clean", null); + config.save(); + + git.add().addFilepattern("Test.txt").call(); + assertEquals( + "[.gitattributes, mode:100644, content:*.txt filter=test][Test.bin, mode:100644, content:Hello again][Test.txt, mode:100644, content:Hello again]", + indexState(CONTENT)); + + config.setString("filter", "test", "clean", null); + config.save(); + } + + @Test + public void testBuiltinSmudgeFilter() throws IOException, GitAPIException { + String builtinCommandName = "jgit://builtin/test/smudge"; + FilterCommandRegistry.register(builtinCommandName, + new TestCommandFactory('s')); + StoredConfig config = git.getRepository().getConfig(); + config.setString("filter", "test", "smudge", builtinCommandName); + config.save(); + + writeTrashFile(".gitattributes", "*.txt filter=test"); + git.add().addFilepattern(".gitattributes").call(); + git.commit().setMessage("add filter").call(); + + writeTrashFile("Test.txt", "Hello again"); + git.add().addFilepattern("Test.txt").call(); + assertEquals( + "[.gitattributes, mode:100644, content:*.txt filter=test][Test.txt, mode:100644, content:Hello again]", + indexState(CONTENT)); + assertEquals("Hello again", read("Test.txt")); + deleteTrashFile("Test.txt"); + git.checkout().addPath("Test.txt").call(); + assertEquals("sHseslslsos sasgsasisn", read("Test.txt")); + + writeTrashFile("Test.bin", "Hello again"); + git.add().addFilepattern("Test.bin").call(); + assertEquals( + "[.gitattributes, mode:100644, content:*.txt filter=test][Test.bin, mode:100644, content:Hello again][Test.txt, mode:100644, content:Hello again]", + indexState(CONTENT)); + deleteTrashFile("Test.bin"); + git.checkout().addPath("Test.bin").call(); + assertEquals("Hello again", read("Test.bin")); + + config.setString("filter", "test", "clean", null); + config.save(); + + git.add().addFilepattern("Test.txt").call(); + assertEquals( + "[.gitattributes, mode:100644, content:*.txt filter=test][Test.bin, mode:100644, content:Hello again][Test.txt, mode:100644, content:sHseslslsos sasgsasisn]", + indexState(CONTENT)); + + config.setString("filter", "test", "clean", null); + config.save(); + } + + @Test + public void testBuiltinCleanAndSmudgeFilter() throws IOException, GitAPIException { + String builtinCommandPrefix = "jgit://builtin/test/"; + FilterCommandRegistry.register(builtinCommandPrefix + "smudge", + new TestCommandFactory('s')); + FilterCommandRegistry.register(builtinCommandPrefix + "clean", + new TestCommandFactory('c')); + StoredConfig config = git.getRepository().getConfig(); + config.setString("filter", "test", "smudge", builtinCommandPrefix+"smudge"); + config.setString("filter", "test", "clean", + builtinCommandPrefix + "clean"); + config.save(); + + writeTrashFile(".gitattributes", "*.txt filter=test"); + git.add().addFilepattern(".gitattributes").call(); + git.commit().setMessage("add filter").call(); + + writeTrashFile("Test.txt", "Hello again"); + git.add().addFilepattern("Test.txt").call(); + assertEquals( + "[.gitattributes, mode:100644, content:*.txt filter=test][Test.txt, mode:100644, content:cHceclclcoc cacgcacicn]", + indexState(CONTENT)); + assertEquals("Hello again", read("Test.txt")); + deleteTrashFile("Test.txt"); + git.checkout().addPath("Test.txt").call(); + assertEquals("scsHscsescslscslscsoscs scsascsgscsascsiscsn", + read("Test.txt")); + + writeTrashFile("Test.bin", "Hello again"); + git.add().addFilepattern("Test.bin").call(); + assertEquals( + "[.gitattributes, mode:100644, content:*.txt filter=test][Test.bin, mode:100644, content:Hello again][Test.txt, mode:100644, content:cHceclclcoc cacgcacicn]", + indexState(CONTENT)); + deleteTrashFile("Test.bin"); + git.checkout().addPath("Test.bin").call(); + assertEquals("Hello again", read("Test.bin")); + + config.setString("filter", "test", "clean", null); + config.save(); + + git.add().addFilepattern("Test.txt").call(); + assertEquals( + "[.gitattributes, mode:100644, content:*.txt filter=test][Test.bin, mode:100644, content:Hello again][Test.txt, mode:100644, content:scsHscsescslscslscsoscs scsascsgscsascsiscsn]", + indexState(CONTENT)); + + config.setString("filter", "test", "clean", null); + config.save(); + } + +} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/RelativeDateFormatterTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/RelativeDateFormatterTest.java index 2901c93885..76687d15a5 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/RelativeDateFormatterTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/util/RelativeDateFormatterTest.java @@ -42,17 +42,16 @@ */ package org.eclipse.jgit.util; -import static org.junit.Assert.assertEquals; -import static org.eclipse.jgit.util.RelativeDateFormatter.YEAR_IN_MILLIS; -import static org.eclipse.jgit.util.RelativeDateFormatter.SECOND_IN_MILLIS; -import static org.eclipse.jgit.util.RelativeDateFormatter.MINUTE_IN_MILLIS; -import static org.eclipse.jgit.util.RelativeDateFormatter.HOUR_IN_MILLIS; import static org.eclipse.jgit.util.RelativeDateFormatter.DAY_IN_MILLIS; +import static org.eclipse.jgit.util.RelativeDateFormatter.HOUR_IN_MILLIS; +import static org.eclipse.jgit.util.RelativeDateFormatter.MINUTE_IN_MILLIS; +import static org.eclipse.jgit.util.RelativeDateFormatter.SECOND_IN_MILLIS; +import static org.eclipse.jgit.util.RelativeDateFormatter.YEAR_IN_MILLIS; +import static org.junit.Assert.assertEquals; import java.util.Date; import org.eclipse.jgit.junit.MockSystemReader; -import org.eclipse.jgit.util.RelativeDateFormatter; import org.junit.After; import org.junit.Before; import org.junit.Test; diff --git a/org.eclipse.jgit.ui/.classpath b/org.eclipse.jgit.ui/.classpath index a14ade4efd..110168ffa1 100644 --- a/org.eclipse.jgit.ui/.classpath +++ b/org.eclipse.jgit.ui/.classpath @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <classpath> - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> <classpathentry kind="src" path="src"/> <classpathentry kind="src" path="resources"/> 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 1ce7cd0219..808ec3a2c6 100644 --- a/org.eclipse.jgit.ui/.settings/org.eclipse.jdt.core.prefs +++ b/org.eclipse.jgit.ui/.settings/org.eclipse.jdt.core.prefs @@ -7,9 +7,9 @@ org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nul org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.7 +org.eclipse.jdt.core.compiler.compliance=1.8 org.eclipse.jdt.core.compiler.debug.lineNumber=generate org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.debug.sourceFile=generate @@ -112,7 +112,7 @@ org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=error -org.eclipse.jdt.core.compiler.source=1.7 +org.eclipse.jdt.core.compiler.source=1.8 org.eclipse.jdt.core.formatter.align_type_members_on_columns=false org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 diff --git a/org.eclipse.jgit.ui/META-INF/MANIFEST.MF b/org.eclipse.jgit.ui/META-INF/MANIFEST.MF index 8d2a77566b..667e3b23a5 100644 --- a/org.eclipse.jgit.ui/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.ui/META-INF/MANIFEST.MF @@ -3,14 +3,14 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Bundle-SymbolicName: org.eclipse.jgit.ui -Bundle-Version: 4.5.3.qualifier +Bundle-Version: 4.6.2.qualifier Bundle-Vendor: %provider_name -Bundle-RequiredExecutionEnvironment: JavaSE-1.7 -Export-Package: org.eclipse.jgit.awtui;version="4.5.3" -Import-Package: org.eclipse.jgit.errors;version="[4.5.3,4.6.0)", - org.eclipse.jgit.lib;version="[4.5.3,4.6.0)", - org.eclipse.jgit.nls;version="[4.5.3,4.6.0)", - org.eclipse.jgit.revplot;version="[4.5.3,4.6.0)", - org.eclipse.jgit.revwalk;version="[4.5.3,4.6.0)", - org.eclipse.jgit.transport;version="[4.5.3,4.6.0)", - org.eclipse.jgit.util;version="[4.5.3,4.6.0)" +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)" diff --git a/org.eclipse.jgit.ui/pom.xml b/org.eclipse.jgit.ui/pom.xml index d8bb1ee414..280399b943 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.5.3-SNAPSHOT</version> + <version>4.6.2-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.ui</artifactId> diff --git a/org.eclipse.jgit/.classpath b/org.eclipse.jgit/.classpath index 04a2be7bdb..cfcf24a51e 100644 --- a/org.eclipse.jgit/.classpath +++ b/org.eclipse.jgit/.classpath @@ -2,7 +2,7 @@ <classpath> <classpathentry kind="src" path="src"/> <classpathentry kind="src" path="resources"/> - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> <classpathentry kind="output" path="bin"/> </classpath> diff --git a/org.eclipse.jgit/.settings/org.eclipse.jdt.core.prefs b/org.eclipse.jgit/.settings/org.eclipse.jdt.core.prefs index bfaf736d6e..4f1759fb3f 100644 --- a/org.eclipse.jgit/.settings/org.eclipse.jdt.core.prefs +++ b/org.eclipse.jgit/.settings/org.eclipse.jdt.core.prefs @@ -7,9 +7,9 @@ org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jgit.annotations.N org.eclipse.jdt.core.compiler.annotation.nullanalysis=enabled org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.7 +org.eclipse.jdt.core.compiler.compliance=1.8 org.eclipse.jdt.core.compiler.debug.lineNumber=generate org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.debug.sourceFile=generate @@ -112,7 +112,7 @@ org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=error org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=error -org.eclipse.jdt.core.compiler.source=1.7 +org.eclipse.jdt.core.compiler.source=1.8 org.eclipse.jdt.core.formatter.align_type_members_on_columns=false org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 diff --git a/org.eclipse.jgit/META-INF/MANIFEST.MF b/org.eclipse.jgit/META-INF/MANIFEST.MF index 7cbedf22e3..701efcff12 100644 --- a/org.eclipse.jgit/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit/META-INF/MANIFEST.MF @@ -2,12 +2,12 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Bundle-SymbolicName: org.eclipse.jgit -Bundle-Version: 4.5.3.qualifier +Bundle-Version: 4.6.2.qualifier Bundle-Localization: plugin Bundle-Vendor: %provider_name Bundle-ActivationPolicy: lazy -Export-Package: org.eclipse.jgit.annotations;version="4.5.3", - org.eclipse.jgit.api;version="4.5.3"; +Export-Package: org.eclipse.jgit.annotations;version="4.6.2", + org.eclipse.jgit.api;version="4.6.2"; uses:="org.eclipse.jgit.revwalk, org.eclipse.jgit.treewalk.filter, org.eclipse.jgit.diff, @@ -21,60 +21,57 @@ Export-Package: org.eclipse.jgit.annotations;version="4.5.3", org.eclipse.jgit.submodule, org.eclipse.jgit.transport, org.eclipse.jgit.merge", - org.eclipse.jgit.api.errors;version="4.5.3";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.errors", - org.eclipse.jgit.attributes;version="4.5.3", - org.eclipse.jgit.blame;version="4.5.3"; + 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"; uses:="org.eclipse.jgit.lib, org.eclipse.jgit.revwalk, org.eclipse.jgit.treewalk.filter, org.eclipse.jgit.diff", - org.eclipse.jgit.diff;version="4.5.3"; + org.eclipse.jgit.diff;version="4.6.2"; uses:="org.eclipse.jgit.patch, org.eclipse.jgit.lib, org.eclipse.jgit.treewalk, org.eclipse.jgit.revwalk, org.eclipse.jgit.treewalk.filter, org.eclipse.jgit.util", - org.eclipse.jgit.dircache;version="4.5.3"; + org.eclipse.jgit.dircache;version="4.6.2"; uses:="org.eclipse.jgit.lib, org.eclipse.jgit.treewalk, org.eclipse.jgit.util, org.eclipse.jgit.events, org.eclipse.jgit.attributes", - org.eclipse.jgit.errors;version="4.5.3"; + org.eclipse.jgit.errors;version="4.6.2"; uses:="org.eclipse.jgit.lib, org.eclipse.jgit.internal.storage.pack, org.eclipse.jgit.transport, org.eclipse.jgit.dircache", - org.eclipse.jgit.events;version="4.5.3";uses:="org.eclipse.jgit.lib", - org.eclipse.jgit.fnmatch;version="4.5.3", - org.eclipse.jgit.gitrepo;version="4.5.3"; + 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"; 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.5.3";x-internal:=true, - org.eclipse.jgit.hooks;version="4.5.3";uses:="org.eclipse.jgit.lib", - org.eclipse.jgit.ignore;version="4.5.3", - org.eclipse.jgit.ignore.internal;version="4.5.3";x-friends:="org.eclipse.jgit.test", - org.eclipse.jgit.internal;version="4.5.3";x-friends:="org.eclipse.jgit.test,org.eclipse.jgit.http.test", - org.eclipse.jgit.internal.ketch;version="4.5.3";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm", - org.eclipse.jgit.internal.storage.dfs;version="4.5.3"; - x-friends:="org.eclipse.jgit.test, - org.eclipse.jgit.http.server, - org.eclipse.jgit.http.test", - org.eclipse.jgit.internal.storage.file;version="4.5.3"; + 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"; x-friends:="org.eclipse.jgit.test, org.eclipse.jgit.junit, org.eclipse.jgit.junit.http, org.eclipse.jgit.http.server, - org.eclipse.jgit.lfs.server, + org.eclipse.jgit.lfs, org.eclipse.jgit.pgm, org.eclipse.jgit.pgm.test", - org.eclipse.jgit.internal.storage.pack;version="4.5.3";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm", - org.eclipse.jgit.internal.storage.reftree;version="4.5.3";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm", - org.eclipse.jgit.lib;version="4.5.3"; + 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"; uses:="org.eclipse.jgit.revwalk, org.eclipse.jgit.treewalk.filter, org.eclipse.jgit.util, @@ -84,32 +81,32 @@ Export-Package: org.eclipse.jgit.annotations;version="4.5.3", org.eclipse.jgit.treewalk, org.eclipse.jgit.transport, org.eclipse.jgit.submodule", - org.eclipse.jgit.merge;version="4.5.3"; + org.eclipse.jgit.merge;version="4.6.2"; uses:="org.eclipse.jgit.lib, org.eclipse.jgit.treewalk, org.eclipse.jgit.revwalk, org.eclipse.jgit.diff, org.eclipse.jgit.dircache, org.eclipse.jgit.api", - org.eclipse.jgit.nls;version="4.5.3", - org.eclipse.jgit.notes;version="4.5.3"; + org.eclipse.jgit.nls;version="4.6.2", + org.eclipse.jgit.notes;version="4.6.2"; uses:="org.eclipse.jgit.lib, org.eclipse.jgit.treewalk, org.eclipse.jgit.revwalk, org.eclipse.jgit.merge", - org.eclipse.jgit.patch;version="4.5.3";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.diff", - org.eclipse.jgit.revplot;version="4.5.3";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.revwalk", - org.eclipse.jgit.revwalk;version="4.5.3"; + 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"; 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.5.3";uses:="org.eclipse.jgit.revwalk,org.eclipse.jgit.lib,org.eclipse.jgit.util", - org.eclipse.jgit.storage.file;version="4.5.3";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.util", - org.eclipse.jgit.storage.pack;version="4.5.3";uses:="org.eclipse.jgit.lib", - org.eclipse.jgit.submodule;version="4.5.3";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.treewalk.filter,org.eclipse.jgit.treewalk", - org.eclipse.jgit.transport;version="4.5.3"; + 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"; uses:="org.eclipse.jgit.transport.resolver, org.eclipse.jgit.revwalk, org.eclipse.jgit.internal.storage.pack, @@ -121,24 +118,25 @@ Export-Package: org.eclipse.jgit.annotations;version="4.5.3", org.eclipse.jgit.transport.http, org.eclipse.jgit.errors, org.eclipse.jgit.storage.pack", - org.eclipse.jgit.transport.http;version="4.5.3";uses:="javax.net.ssl", - org.eclipse.jgit.transport.resolver;version="4.5.3";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.transport", - org.eclipse.jgit.treewalk;version="4.5.3"; + 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"; 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.5.3";uses:="org.eclipse.jgit.treewalk", - org.eclipse.jgit.util;version="4.5.3"; + org.eclipse.jgit.treewalk.filter;version="4.6.2";uses:="org.eclipse.jgit.treewalk", + org.eclipse.jgit.util;version="4.6.2"; uses:="org.eclipse.jgit.lib, org.eclipse.jgit.transport.http, org.eclipse.jgit.storage.file, org.ietf.jgss", - org.eclipse.jgit.util.io;version="4.5.3" -Bundle-RequiredExecutionEnvironment: JavaSE-1.7 -Import-Package: com.googlecode.javaewah;version="[0.7.9,0.8.0)", + org.eclipse.jgit.util.io;version="4.6.2", + org.eclipse.jgit.util.time;version="4.6.2" +Bundle-RequiredExecutionEnvironment: JavaSE-1.8 +Import-Package: com.googlecode.javaewah;version="[1.1.6,2.0.0)", com.jcraft.jsch;version="[0.1.37,0.2.0)", javax.crypto, javax.net.ssl, diff --git a/org.eclipse.jgit/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit/META-INF/SOURCE-MANIFEST.MF index 45a55a8694..c863b047aa 100644 --- a/org.eclipse.jgit/META-INF/SOURCE-MANIFEST.MF +++ b/org.eclipse.jgit/META-INF/SOURCE-MANIFEST.MF @@ -3,5 +3,5 @@ Bundle-ManifestVersion: 2 Bundle-Name: org.eclipse.jgit - Sources Bundle-SymbolicName: org.eclipse.jgit.source Bundle-Vendor: Eclipse.org - JGit -Bundle-Version: 4.5.3.qualifier -Eclipse-SourceBundle: org.eclipse.jgit;version="4.5.3.qualifier";roots="." +Bundle-Version: 4.6.2.qualifier +Eclipse-SourceBundle: org.eclipse.jgit;version="4.6.2.qualifier";roots="." diff --git a/org.eclipse.jgit/pom.xml b/org.eclipse.jgit/pom.xml index ed517be8be..cf935ae0f3 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.5.3-SNAPSHOT</version> + <version>4.6.2-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit</artifactId> diff --git a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties index b5b04b4743..992b80b32a 100644 --- a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties +++ b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties @@ -39,6 +39,7 @@ bitmapsMustBePrepared=Bitmaps must be prepared before they may be written. blameNotCommittedYet=Not Committed Yet blobNotFound=Blob not found: {0} blobNotFoundForPath=Blob not found: {0} for path: {1} +blockSizeNotPowerOf2=blockSize must be a power of 2 branchNameInvalid=Branch name {0} is not allowed buildingBitmaps=Building bitmaps cachedPacksPreventsIndexCreation=Using cached packs prevents index creation @@ -115,6 +116,7 @@ checkoutConflictWithFiles=Checkout conflict with files: {0} checkoutUnexpectedResult=Checkout returned unexpected result {0} classCastNotA=Not a {0} cloneNonEmptyDirectory=Destination path "{0}" already exists and is not an empty directory +closed=closed collisionOn=Collision on {0} commandRejectedByHook=Rejected by "{0}" hook.\n{1} commandWasCalledInTheWrongState=Command {0} was called in the wrong state @@ -279,6 +281,7 @@ expectedLessThanGot=expected less than ''{0}'', got ''{1}'' 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 +failedToDetermineFilterDefinition=An exception occured while determining filter definitions failedUpdatingRefs=failed updating refs failureDueToOneOfTheFollowing=Failure due to one of the following: failureUpdatingFETCH_HEAD=Failure updating FETCH_HEAD: {0} @@ -366,6 +369,7 @@ invalidTagOption=Invalid tag option: {0} invalidTimeout=Invalid timeout: {0} invalidTimeUnitValue2=Invalid time unit value: {0}.{1}={2} invalidTimeUnitValue3=Invalid time unit value: {0}.{1}.{2}={3} +invalidTreeZeroLengthName=Cannot append a tree entry with zero-length name invalidURL=Invalid URL {0} invalidWildcards=Invalid wildcards {0} invalidRefSpec=Invalid refspec {0} @@ -463,6 +467,7 @@ packDoesNotMatchIndex=Pack {0} does not match index packedRefsHandleIsStale=packed-refs handle is stale, {0}. retry packetSizeMustBeAtLeast=packet size {0} must be >= {1} packetSizeMustBeAtMost=packet size {0} must be <= {1} +packedRefsCorruptionDetected=packed-refs corruption detected: {0} packfileCorruptionDetected=Packfile corruption detected: {0} packFileInvalid=Pack file invalid: {0} packfileIsTruncated=Packfile {0} is truncated. @@ -601,6 +606,7 @@ tagAlreadyExists=tag ''{0}'' already exists tagNameInvalid=tag name {0} is invalid tagOnRepoWithoutHEADCurrentlyNotSupported=Tag on repository without HEAD currently not supported theFactoryMustNotBeNull=The factory must not be null +timeIsUncertain=Time is uncertain timerAlreadyTerminated=Timer already terminated tooManyIncludeRecursions=Too many recursions; circular includes in config file(s)? topologicalSortRequired=Topological sort required. @@ -670,6 +676,7 @@ unsupportedMark=Mark not supported unsupportedOperationNotAddAtEnd=Not add-at-end: {0} unsupportedPackIndexVersion=Unsupported pack index version {0} unsupportedPackVersion=Unsupported pack version {0}. +unsupportedRepositoryDescription=Repository description not supported updatingHeadFailed=Updating HEAD failed updatingReferences=Updating references updatingRefFailed=Updating the ref {0} to {1} failed. ReturnCode from RefUpdate.update() was {2} 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 1f37833a41..16ec1463c9 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/AddCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/AddCommand.java @@ -224,6 +224,11 @@ public class AddCommand extends GitCommand<DirCache> { entry.setLength(f.getEntryLength()); entry.setLastModified(f.getEntryLastModified()); long len = f.getEntryContentLength(); + // We read and filter the content multiple times. + // f.getEntryContentLength() reads and filters the input and + // inserter.insert(...) does it again. That's because an + // ObjectInserter needs to know the length before it starts + // inserting. TODO: Fix this by using Buffers. try (InputStream in = f.openEntryStream()) { ObjectId id = inserter.insert(OBJ_BLOB, len, in); entry.setObjectId(id); 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 d803efd649..2a2e07ddda 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/BlameCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/BlameCommand.java @@ -61,9 +61,9 @@ import org.eclipse.jgit.diff.RawTextComparator; import org.eclipse.jgit.dircache.DirCache; import org.eclipse.jgit.lib.AnyObjectId; import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.lib.CoreConfig.AutoCRLF; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.Repository; -import org.eclipse.jgit.lib.CoreConfig.AutoCRLF; import org.eclipse.jgit.treewalk.WorkingTreeOptions; import org.eclipse.jgit.util.IO; import org.eclipse.jgit.util.io.AutoLFInputStream; @@ -248,11 +248,12 @@ public class BlameCommand extends GitCommand<BlameResult> { rawText = new RawText(inTree); break; case TRUE: - AutoLFInputStream in = new AutoLFInputStream( - new FileInputStream(inTree), true); - // Canonicalization should lead to same or shorter length - // (CRLF to LF), so the file size on disk is an upper size bound - rawText = new RawText(toByteArray(in, (int) inTree.length())); + try (AutoLFInputStream in = new AutoLFInputStream( + new FileInputStream(inTree), true)) { + // Canonicalization should lead to same or shorter length + // (CRLF to LF), so the file size on disk is an upper size bound + rawText = new RawText(toByteArray(in, (int) inTree.length())); + } break; default: throw new IllegalArgumentException( 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 65508eff40..c17ae5c00d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutCommand.java @@ -318,7 +318,9 @@ public class CheckoutCommand extends GitCommand<Ref> { if (!dco.getToBeDeleted().isEmpty()) { status = new CheckoutResult(Status.NONDELETED, - dco.getToBeDeleted()); + dco.getToBeDeleted(), + new ArrayList<String>(dco.getUpdated().keySet()), + dco.getRemoved()); } else status = new CheckoutResult(new ArrayList<String>(dco .getUpdated().keySet()), dco.getRemoved()); @@ -365,6 +367,26 @@ public class CheckoutCommand extends GitCommand<Ref> { } /** + * Add multiple slash-separated paths to the list of paths to check out. To + * check out all paths, use {@link #setAllPaths(boolean)}. + * <p> + * If this option is set, neither the {@link #setCreateBranch(boolean)} nor + * {@link #setName(String)} option is considered. In other words, these + * options are exclusive. + * + * @param p + * paths to update in the working tree and index (with + * <code>/</code> as separator) + * @return {@code this} + * @since 4.6 + */ + public CheckoutCommand addPaths(List<String> p) { + checkCallable(); + this.paths.addAll(p); + return this; + } + + /** * Set whether to checkout all paths. * <p> * This options should be used when you want to do a path checkout on the 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 6a1bfb8f0e..92a67f46af 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutResult.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutResult.java @@ -113,6 +113,28 @@ public class CheckoutResult { * {@link Status#CONFLICTS} or {@link Status#NONDELETED}. */ CheckoutResult(Status status, List<String> fileList) { + this(status, fileList, null, null); + } + + /** + * Create a new fail result. If status is {@link Status#CONFLICTS}, + * <code>fileList</code> is a list of conflicting files, if status is + * {@link Status#NONDELETED}, <code>fileList</code> is a list of not deleted + * files. All other values ignore <code>fileList</code>. To create a result + * for {@link Status#OK}, see {@link #CheckoutResult(List, List)}. + * + * @param status + * the failure status + * @param fileList + * the list of files to store, status has to be either + * {@link Status#CONFLICTS} or {@link Status#NONDELETED}. + * @param modified + * the modified files + * @param removed + * the removed files. + */ + CheckoutResult(Status status, List<String> fileList, List<String> modified, + List<String> removed) { myStatus = status; if (status == Status.CONFLICTS) this.conflictList = fileList; @@ -123,8 +145,8 @@ public class CheckoutResult { else this.undeletedList = new ArrayList<String>(0); - this.modifiedList = new ArrayList<String>(0); - this.removedList = new ArrayList<String>(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 e82a69798f..276bf96ea2 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CherryPickCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CherryPickCommand.java @@ -330,4 +330,15 @@ public class CherryPickCommand extends GitCommand<CherryPickResult> { String headName = Repository.shortenRefName(targetRefName); return headName; } + + @SuppressWarnings("nls") + @Override + public String toString() { + return "CherryPickCommand [repo=" + repo + ",\ncommits=" + commits + + ",\nmainlineParentNumber=" + mainlineParentNumber + + ", noCommit=" + noCommit + ", ourCommitName=" + ourCommitName + + ", reflogPrefix=" + reflogPrefix + ", strategy=" + strategy + + "]"; + } + } 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 38b10971f4..ced1863719 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/MergeCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/MergeCommand.java @@ -381,6 +381,7 @@ public class MergeCommand extends GitCommand<MergeResult> { .call().getId(); } mergeStatus = MergeStatus.MERGED; + getRepository().autoGC(monitor); } if (commit && squash) { msg = JGitText.get().squashCommitNotUpdatingHEAD; 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 2d6a76b390..d10cc3d715 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java @@ -400,8 +400,8 @@ public class RebaseCommand extends GitCommand<RebaseResult> { boolean conflicts = false; if (rebaseState.getFile(AUTOSTASH).exists()) { String stash = rebaseState.readFile(AUTOSTASH); - try { - Git.wrap(repo).stashApply().setStashRef(stash) + try (Git git = Git.wrap(repo)) { + git.stashApply().setStashRef(stash) .ignoreRepositoryState(true).setStrategy(strategy) .call(); } catch (StashApplyFailureException e) { @@ -463,8 +463,10 @@ public class RebaseCommand extends GitCommand<RebaseResult> { String oldMessage = commitToPick.getFullMessage(); String newMessage = interactiveHandler .modifyCommitMessage(oldMessage); - newHead = new Git(repo).commit().setMessage(newMessage) - .setAmend(true).setNoVerify(true).call(); + try (Git git = new Git(repo)) { + newHead = git.commit().setMessage(newMessage).setAmend(true) + .setNoVerify(true).call(); + } return null; case EDIT: rebaseState.createFile(AMEND, commitToPick.name()); @@ -693,6 +695,7 @@ public class RebaseCommand extends GitCommand<RebaseResult> { String headName = rebaseState.readFile(HEAD_NAME); updateHead(headName, finalHead, upstreamCommit); boolean stashConflicts = autoStashApply(); + getRepository().autoGC(monitor); FileUtils.delete(rebaseState.getDir(), FileUtils.RECURSIVE); if (stashConflicts) return RebaseResult.STASH_APPLY_CONFLICTS_RESULT; @@ -752,12 +755,12 @@ public class RebaseCommand extends GitCommand<RebaseResult> { GitAPIException, CheckoutConflictException { Ref ref = repo.exactRef(Constants.ORIG_HEAD); ObjectId orig_head = ref == null ? null : ref.getObjectId(); - try { - // we have already commited the cherry-picked commit. + try (Git git = Git.wrap(repo)) { + // we have already committed the cherry-picked commit. // what we need is to have changes introduced by this // commit to be on the index // resetting is a workaround - Git.wrap(repo).reset().setMode(ResetType.SOFT) + git.reset().setMode(ResetType.SOFT) .setRef("HEAD~1").call(); //$NON-NLS-1$ } finally { // set ORIG_HEAD back to where we started because soft 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 3ceff843a5..106988d4d4 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ResetCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ResetCommand.java @@ -432,4 +432,12 @@ public class ResetCommand extends GitCommand<Ref> { repo.writeMergeCommitMsg(null); } + @SuppressWarnings("nls") + @Override + public String toString() { + return "ResetCommand [repo=" + repo + ", ref=" + ref + ", mode=" + mode + + ", isReflogDisabled=" + isReflogDisabled + ", filepaths=" + + filepaths + "]"; + } + } 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 fbb24c1577..b0f772e0aa 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleAddCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleAddCommand.java @@ -133,7 +133,9 @@ public class SubmoduleAddCommand extends */ protected boolean submoduleExists() throws IOException { TreeFilter filter = PathFilter.create(path); - return SubmoduleWalk.forIndex(repo).setFilter(filter).next(); + try (SubmoduleWalk w = SubmoduleWalk.forIndex(repo)) { + return w.setFilter(filter).next(); + } } /** @@ -178,7 +180,11 @@ public class SubmoduleAddCommand extends clone.setURI(resolvedUri); if (monitor != null) clone.setProgressMonitor(monitor); - Repository subRepo = clone.call().getRepository(); + Repository subRepo = null; + try (Git git = clone.call()) { + subRepo = git.getRepository(); + subRepo.incrementOpen(); + } // Save submodule URL to parent repository's config StoredConfig config = repo.getConfig(); 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 0ed02acc82..1dbe3681bf 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleInitCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleInitCommand.java @@ -94,8 +94,7 @@ public class SubmoduleInitCommand extends GitCommand<Collection<String>> { public Collection<String> call() throws GitAPIException { checkCallable(); - try { - SubmoduleWalk generator = SubmoduleWalk.forIndex(repo); + try (SubmoduleWalk generator = SubmoduleWalk.forIndex(repo)) { if (!paths.isEmpty()) generator.setFilter(PathFilterGroup.createFromStrings(paths)); StoredConfig config = repo.getConfig(); 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 6e89f9873e..a1ea790d0d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleStatusCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleStatusCommand.java @@ -54,9 +54,9 @@ import org.eclipse.jgit.errors.ConfigInvalidException; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.Repository; -import org.eclipse.jgit.submodule.SubmoduleWalk; import org.eclipse.jgit.submodule.SubmoduleStatus; import org.eclipse.jgit.submodule.SubmoduleStatusType; +import org.eclipse.jgit.submodule.SubmoduleWalk; import org.eclipse.jgit.treewalk.filter.PathFilterGroup; /** @@ -94,8 +94,7 @@ public class SubmoduleStatusCommand extends public Map<String, SubmoduleStatus> call() throws GitAPIException { checkCallable(); - try { - SubmoduleWalk generator = SubmoduleWalk.forIndex(repo); + try (SubmoduleWalk generator = SubmoduleWalk.forIndex(repo)) { if (!paths.isEmpty()) generator.setFilter(PathFilterGroup.createFromStrings(paths)); Map<String, SubmoduleStatus> statuses = new HashMap<String, SubmoduleStatus>(); 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 024f0bebde..088eedc2dc 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleSyncCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleSyncCommand.java @@ -111,8 +111,7 @@ public class SubmoduleSyncCommand extends GitCommand<Map<String, String>> { public Map<String, String> call() throws GitAPIException { checkCallable(); - try { - SubmoduleWalk generator = SubmoduleWalk.forIndex(repo); + try (SubmoduleWalk generator = SubmoduleWalk.forIndex(repo)) { if (!paths.isEmpty()) generator.setFilter(PathFilterGroup.createFromStrings(paths)); Map<String, String> synced = new HashMap<String, String>(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/errors/StashApplyFailureException.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/errors/StashApplyFailureException.java index 1d54f77db8..222c1db2bb 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/errors/StashApplyFailureException.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/errors/StashApplyFailureException.java @@ -1,7 +1,5 @@ package org.eclipse.jgit.api.errors; -import org.eclipse.jgit.api.errors.GitAPIException; - /** * Thrown from StashApplyCommand when stash apply fails */ diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/attributes/AttributesHandler.java b/org.eclipse.jgit/src/org/eclipse/jgit/attributes/AttributesHandler.java index 19e4afdf92..3bf4179e7d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/attributes/AttributesHandler.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/attributes/AttributesHandler.java @@ -54,8 +54,8 @@ import org.eclipse.jgit.lib.FileMode; import org.eclipse.jgit.treewalk.AbstractTreeIterator; import org.eclipse.jgit.treewalk.CanonicalTreeParser; import org.eclipse.jgit.treewalk.TreeWalk; -import org.eclipse.jgit.treewalk.WorkingTreeIterator; import org.eclipse.jgit.treewalk.TreeWalk.OperationType; +import org.eclipse.jgit.treewalk.WorkingTreeIterator; /** * The attributes handler knows how to retrieve, parse and merge attributes from diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/attributes/FilterCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/attributes/FilterCommand.java new file mode 100644 index 0000000000..10be58880c --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/attributes/FilterCommand.java @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2016, Christian Halstrick <christian.halstrick@sap.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.attributes; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +/** + * An abstraction for JGit's builtin implementations for hooks and filters. + * Instead of spawning an external processes to start a filter/hook and to pump + * data from/to stdin/stdout these builtin commmands may be used. They are + * constructed by {@link FilterCommandFactory}. + * + * @since 4.6 + */ +public abstract class FilterCommand { + /** + * The {@link InputStream} this command should read from + */ + protected InputStream in; + + /** + * The {@link OutputStream} this command should write to + */ + protected OutputStream out; + + /** + * @param in + * The {@link InputStream} this command should read from + * @param out + * The {@link OutputStream} this command should write to + */ + public FilterCommand(InputStream in, OutputStream out) { + this.in = in; + this.out = out; + } + + /** + * Execute the command. The command is supposed to read data from + * {@link #in} and to write the result to {@link #out}. It returns the + * number of bytes it read from {@link #in}. It should be called in a loop + * until it returns -1 signaling that the {@link InputStream} is completely + * processed. + * + * @return the number of bytes read from the {@link InputStream} or -1. -1 + * means that the {@link InputStream} is completely processed. + * @throws IOException + * when {@link IOException} occured while reading from + * {@link #in} or writing to {@link #out} + * + */ + public abstract int run() throws IOException; +} diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/attributes/FilterCommandFactory.java b/org.eclipse.jgit/src/org/eclipse/jgit/attributes/FilterCommandFactory.java new file mode 100644 index 0000000000..6b973da35f --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/attributes/FilterCommandFactory.java @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2016, Christian Halstrick <christian.halstrick@sap.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.attributes; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import org.eclipse.jgit.lib.Repository; + +/** + * The factory responsible for creating instances of {@link FilterCommand}. + * + * @since 4.6 + */ +public interface FilterCommandFactory { + /** + * Create a new {@link FilterCommand}. + * + * @param db + * the repository this command should work on + * @param in + * the {@link InputStream} this command should read from + * @param out + * the {@link OutputStream} this command should write to + * @return the created {@link FilterCommand} + * @throws IOException + * thrown when the command constructor throws an IOException + */ + public FilterCommand create(Repository db, InputStream in, + OutputStream out) throws IOException; + +} diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/attributes/FilterCommandRegistry.java b/org.eclipse.jgit/src/org/eclipse/jgit/attributes/FilterCommandRegistry.java new file mode 100644 index 0000000000..3fbaedb051 --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/attributes/FilterCommandRegistry.java @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2016, Matthias Sohn <matthias.sohn@sap.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.attributes; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +import org.eclipse.jgit.lib.Repository; + +/** + * Registry for built-in filters + * + * @since 4.6 + */ +public class FilterCommandRegistry { + private static ConcurrentHashMap<String, FilterCommandFactory> filterCommandRegistry = new ConcurrentHashMap<>(); + + /** + * Registers a {@link FilterCommandFactory} responsible for creating + * {@link FilterCommand}s for a certain command name. If the factory f1 is + * registered for the name "jgit://builtin/x" then a call to + * <code>getCommand("jgit://builtin/x", ...)</code> will call + * <code>f1(...)</code> to create a new instance of {@link FilterCommand} + * + * @param filterCommandName + * the command name for which this factory is registered + * @param factory + * the factory responsible for creating {@link FilterCommand}s + * for the specified name + * @return the previous factory associated with <tt>commandName</tt>, or + * <tt>null</tt> if there was no mapping for <tt>commandName</tt> + */ + public static FilterCommandFactory register(String filterCommandName, + FilterCommandFactory factory) { + return filterCommandRegistry.put(filterCommandName, factory); + } + + /** + * Unregisters the {@link FilterCommandFactory} registered for the given + * command name + * + * @param filterCommandName + * the FilterCommandFactory's filter command name + * @return the previous factory associated with <tt>filterCommandName</tt>, + * or <tt>null</tt> if there was no mapping for <tt>commandName</tt> + */ + public static FilterCommandFactory unregister(String filterCommandName) { + return filterCommandRegistry.remove(filterCommandName); + } + + /** + * Checks whether any {@link FilterCommandFactory} is registered for a given + * command name + * + * @param filterCommandName + * the name for which the registry should be checked + * @return <code>true</code> if any factory was registered for the name + */ + public static boolean isRegistered(String filterCommandName) { + return filterCommandRegistry.containsKey(filterCommandName); + } + + /** + * @return Set of commandNames for which a {@link FilterCommandFactory} is + * registered + */ + public static Set<String> getRegisteredFilterCommands() { + return filterCommandRegistry.keySet(); + } + + /** + * Creates a new {@link FilterCommand} for the given name. A factory must be + * registered for the name in advance. + * + * @param filterCommandName + * The name for which a new {@link FilterCommand} should be + * created + * @param db + * the repository this command should work on + * @param in + * the {@link InputStream} this {@link FilterCommand} should read + * from + * @param out + * the {@link OutputStream} this {@link FilterCommand} should + * write to + * @return the command if a command could be created or <code>null</code> if + * there was no factory registered for that name + * @throws IOException + */ + public static FilterCommand createFilterCommand(String filterCommandName, + Repository db, InputStream in, OutputStream out) + throws IOException { + FilterCommandFactory cf = filterCommandRegistry.get(filterCommandName); + return (cf == null) ? null : cf.create(db, in, out); + } + +} 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 b9101c028c..b0cf8be076 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCache.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCache.java @@ -46,6 +46,7 @@ package org.eclipse.jgit.dircache; import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; import java.io.EOFException; import java.io.File; import java.io.FileInputStream; @@ -86,7 +87,6 @@ import org.eclipse.jgit.util.IO; import org.eclipse.jgit.util.MutableInteger; import org.eclipse.jgit.util.NB; import org.eclipse.jgit.util.TemporaryBuffer; -import org.eclipse.jgit.util.io.SafeBufferedOutputStream; /** * Support for the Git dircache (aka index file). @@ -634,9 +634,9 @@ public class DirCache { public void write() throws IOException { final LockFile tmp = myLock; requireLocked(tmp); - try { - writeTo(liveFile.getParentFile(), - new SafeBufferedOutputStream(tmp.getOutputStream())); + try (OutputStream o = tmp.getOutputStream(); + OutputStream bo = new BufferedOutputStream(o)) { + writeTo(liveFile.getParentFile(), bo); } catch (IOException err) { tmp.unlock(); throw err; 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 8af7e46a07..c3184437b4 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java @@ -54,6 +54,8 @@ import java.util.List; import java.util.Map; import org.eclipse.jgit.api.errors.FilterFailedException; +import org.eclipse.jgit.attributes.FilterCommand; +import org.eclipse.jgit.attributes.FilterCommandRegistry; import org.eclipse.jgit.errors.CheckoutConflictException; import org.eclipse.jgit.errors.CorruptObjectException; import org.eclipse.jgit.errors.IncorrectObjectTypeException; @@ -86,11 +88,15 @@ import org.eclipse.jgit.util.FileUtils; import org.eclipse.jgit.util.RawParseUtils; import org.eclipse.jgit.util.SystemReader; import org.eclipse.jgit.util.io.EolStreamTypeUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * This class handles checking out one or two trees merging with the index. */ public class DirCacheCheckout { + private static Logger LOG = LoggerFactory.getLogger(DirCacheCheckout.class); + private static final int MAX_EXCEPTION_TEXT_SIZE = 10 * 1024; /** @@ -1303,45 +1309,19 @@ public class DirCacheCheckout { } else { nonNullEolStreamType = EolStreamType.DIRECT; } - OutputStream channel = EolStreamTypeUtil.wrapOutputStream( - new FileOutputStream(tmpFile), nonNullEolStreamType); - if (checkoutMetadata.smudgeFilterCommand != null) { - ProcessBuilder filterProcessBuilder = fs.runInShell( - checkoutMetadata.smudgeFilterCommand, new String[0]); - filterProcessBuilder.directory(repo.getWorkTree()); - filterProcessBuilder.environment().put(Constants.GIT_DIR_KEY, - repo.getDirectory().getAbsolutePath()); - ExecutionResult result; - int rc; - try { - // TODO: wire correctly with AUTOCRLF - result = fs.execute(filterProcessBuilder, ol.openStream()); - rc = result.getRc(); - if (rc == 0) { - result.getStdout().writeTo(channel, - NullProgressMonitor.INSTANCE); + try (OutputStream channel = EolStreamTypeUtil.wrapOutputStream( + new FileOutputStream(tmpFile), nonNullEolStreamType)) { + if (checkoutMetadata.smudgeFilterCommand != null) { + if (FilterCommandRegistry + .isRegistered(checkoutMetadata.smudgeFilterCommand)) { + runBuiltinFilterCommand(repo, checkoutMetadata, ol, + channel); + } else { + runExternalFilterCommand(repo, entry, checkoutMetadata, ol, + fs, channel); } - } catch (IOException | InterruptedException e) { - throw new IOException(new FilterFailedException(e, - checkoutMetadata.smudgeFilterCommand, - entry.getPathString())); - - } finally { - channel.close(); - } - if (rc != 0) { - throw new IOException(new FilterFailedException(rc, - checkoutMetadata.smudgeFilterCommand, - entry.getPathString(), - result.getStdout().toByteArray(MAX_EXCEPTION_TEXT_SIZE), - RawParseUtils.decode(result.getStderr() - .toByteArray(MAX_EXCEPTION_TEXT_SIZE)))); - } - } else { - try { + } else { ol.copyTo(channel); - } finally { - channel.close(); } } // The entry needs to correspond to the on-disk filesize. If the content @@ -1382,6 +1362,63 @@ public class DirCacheCheckout { entry.setLastModified(fs.lastModified(f)); } + // Run an external filter command + private static void runExternalFilterCommand(Repository repo, + DirCacheEntry entry, + CheckoutMetadata checkoutMetadata, ObjectLoader ol, FS fs, + OutputStream channel) throws IOException { + ProcessBuilder filterProcessBuilder = fs.runInShell( + checkoutMetadata.smudgeFilterCommand, new String[0]); + filterProcessBuilder.directory(repo.getWorkTree()); + filterProcessBuilder.environment().put(Constants.GIT_DIR_KEY, + repo.getDirectory().getAbsolutePath()); + ExecutionResult result; + int rc; + try { + // TODO: wire correctly with AUTOCRLF + result = fs.execute(filterProcessBuilder, ol.openStream()); + rc = result.getRc(); + if (rc == 0) { + result.getStdout().writeTo(channel, + NullProgressMonitor.INSTANCE); + } + } catch (IOException | InterruptedException e) { + throw new IOException(new FilterFailedException(e, + checkoutMetadata.smudgeFilterCommand, + entry.getPathString())); + } + if (rc != 0) { + throw new IOException(new FilterFailedException(rc, + checkoutMetadata.smudgeFilterCommand, + entry.getPathString(), + result.getStdout().toByteArray(MAX_EXCEPTION_TEXT_SIZE), + RawParseUtils.decode(result.getStderr() + .toByteArray(MAX_EXCEPTION_TEXT_SIZE)))); + } + } + + // Run a builtin filter command + private static void runBuiltinFilterCommand(Repository repo, + CheckoutMetadata checkoutMetadata, ObjectLoader ol, + OutputStream channel) throws MissingObjectException, IOException { + FilterCommand command = null; + try { + command = FilterCommandRegistry.createFilterCommand( + checkoutMetadata.smudgeFilterCommand, repo, ol.openStream(), + channel); + } catch (IOException e) { + LOG.error(JGitText.get().failedToDetermineFilterDefinition, e); + // In case an IOException occurred during creating of the command + // then proceed as if there would not have been a builtin filter. + ol.copyTo(channel); + } + if (command != null) { + while (command.run() != -1) { + // loop as long as command.run() tells there is work to do + } + } + } + @SuppressWarnings("deprecation") private static void checkValidPath(CanonicalTreeParser t) throws InvalidPathException { 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 2370ae14c7..8a35d35fea 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/ManifestParser.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/ManifestParser.java @@ -215,10 +215,13 @@ public class ManifestParser extends DefaultHandler { attributes.getValue("dest"))); //$NON-NLS-1$ } else if ("include".equals(qName)) { //$NON-NLS-1$ String name = attributes.getValue("name"); //$NON-NLS-1$ - InputStream is = null; if (includedReader != null) { - try { - is = includedReader.readIncludeFile(name); + try (InputStream is = includedReader.readIncludeFile(name)) { + if (is == null) { + throw new SAXException( + RepoText.get().errorIncludeNotImplemented); + } + read(is); } catch (Exception e) { throw new SAXException(MessageFormat.format( RepoText.get().errorIncludeFile, name), e); @@ -226,22 +229,13 @@ public class ManifestParser extends DefaultHandler { } else if (filename != null) { int index = filename.lastIndexOf('/'); String path = filename.substring(0, index + 1) + name; - try { - is = new FileInputStream(path); + try (InputStream is = new FileInputStream(path)) { + read(is); } catch (IOException e) { throw new SAXException(MessageFormat.format( RepoText.get().errorIncludeFile, path), e); } } - if (is == null) { - throw new SAXException( - RepoText.get().errorIncludeNotImplemented); - } - try { - read(is); - } catch (IOException e) { - throw new SAXException(e); - } } } 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 9b7f094d0f..86dbabca0b 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java @@ -180,17 +180,11 @@ public class RepoCommand extends GitCommand<RevCommit> { 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$ - Repository repo = Git - .cloneRepository() - .setBare(true) - .setDirectory(dir) - .setURI(uri) - .call() - .getRepository(); - try { + try (Git git = Git.cloneRepository().setBare(true).setDirectory(dir) + .setURI(uri).call(); + Repository repo = git.getRepository()) { return readFileFromRepo(repo, ref, path); } finally { - repo.close(); FileUtils.delete(dir, FileUtils.RECURSIVE); } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/FastIgnoreRule.java b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/FastIgnoreRule.java index eb081adb19..ef67d49419 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/ignore/FastIgnoreRule.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/ignore/FastIgnoreRule.java @@ -42,10 +42,11 @@ */ package org.eclipse.jgit.ignore; +import static org.eclipse.jgit.ignore.internal.IMatcher.NO_MATCH; +import static org.eclipse.jgit.ignore.internal.Strings.isDirectoryPattern; import static org.eclipse.jgit.ignore.internal.Strings.stripTrailing; import static org.eclipse.jgit.ignore.internal.Strings.stripTrailingWhitespace; -import static org.eclipse.jgit.ignore.internal.Strings.isDirectoryPattern; -import static org.eclipse.jgit.ignore.internal.IMatcher.NO_MATCH; + import org.eclipse.jgit.errors.InvalidPatternException; import org.eclipse.jgit.ignore.internal.IMatcher; import org.eclipse.jgit.ignore.internal.PathMatcher; 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 758f71d27a..ada5bf7116 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java @@ -98,6 +98,7 @@ public class JGitText extends TranslationBundle { /***/ public String blameNotCommittedYet; /***/ public String blobNotFound; /***/ public String blobNotFoundForPath; + /***/ public String blockSizeNotPowerOf2; /***/ public String branchNameInvalid; /***/ public String buildingBitmaps; /***/ public String cachedPacksPreventsIndexCreation; @@ -174,6 +175,7 @@ public class JGitText extends TranslationBundle { /***/ public String checkoutUnexpectedResult; /***/ public String classCastNotA; /***/ public String cloneNonEmptyDirectory; + /***/ public String closed; /***/ public String collisionOn; /***/ public String commandRejectedByHook; /***/ public String commandWasCalledInTheWrongState; @@ -338,6 +340,7 @@ public class JGitText extends TranslationBundle { /***/ public String expectedPktLineWithService; /***/ public String expectedReceivedContentType; /***/ public String expectedReportForRefNotReceived; + /***/ public String failedToDetermineFilterDefinition; /***/ public String failedUpdatingRefs; /***/ public String failureDueToOneOfTheFollowing; /***/ public String failureUpdatingFETCH_HEAD; @@ -424,6 +427,7 @@ public class JGitText extends TranslationBundle { /***/ public String invalidTimeout; /***/ public String invalidTimeUnitValue2; /***/ public String invalidTimeUnitValue3; + /***/ public String invalidTreeZeroLengthName; /***/ public String invalidURL; /***/ public String invalidWildcards; /***/ public String invalidRefSpec; @@ -522,6 +526,7 @@ public class JGitText extends TranslationBundle { /***/ public String packedRefsHandleIsStale; /***/ public String packetSizeMustBeAtLeast; /***/ public String packetSizeMustBeAtMost; + /***/ public String packedRefsCorruptionDetected; /***/ public String packfileCorruptionDetected; /***/ public String packFileInvalid; /***/ public String packfileIsTruncated; @@ -661,6 +666,7 @@ public class JGitText extends TranslationBundle { /***/ public String tagOnRepoWithoutHEADCurrentlyNotSupported; /***/ public String transactionAborted; /***/ public String theFactoryMustNotBeNull; + /***/ public String timeIsUncertain; /***/ public String timerAlreadyTerminated; /***/ public String tooManyIncludeRecursions; /***/ public String topologicalSortRequired; @@ -729,6 +735,7 @@ public class JGitText extends TranslationBundle { /***/ public String unsupportedOperationNotAddAtEnd; /***/ public String unsupportedPackIndexVersion; /***/ public String unsupportedPackVersion; + /***/ public String unsupportedRepositoryDescription; /***/ public String updatingHeadFailed; /***/ public String updatingReferences; /***/ public String updatingRefFailed; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/ElectionRound.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/ElectionRound.java index 014eab2b45..1221ddd8d2 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/ElectionRound.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/ElectionRound.java @@ -43,10 +43,12 @@ package org.eclipse.jgit.internal.ketch; +import static java.util.concurrent.TimeUnit.SECONDS; import static org.eclipse.jgit.internal.ketch.KetchConstants.TERM; import java.io.IOException; import java.util.List; +import java.util.concurrent.TimeoutException; import org.eclipse.jgit.lib.CommitBuilder; import org.eclipse.jgit.lib.ObjectId; @@ -55,6 +57,7 @@ import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.TreeFormatter; import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevWalk; +import org.eclipse.jgit.util.time.ProposedTimestamp; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -75,9 +78,11 @@ class ElectionRound extends Round { void start() throws IOException { ObjectId id; try (Repository git = leader.openRepository(); + ProposedTimestamp ts = getSystem().getClock().propose(); ObjectInserter inserter = git.newObjectInserter()) { - id = bumpTerm(git, inserter); + id = bumpTerm(git, ts, inserter); inserter.flush(); + blockUntil(ts); } runAsync(id); } @@ -91,12 +96,17 @@ class ElectionRound extends Round { return term; } - private ObjectId bumpTerm(Repository git, ObjectInserter inserter) - throws IOException { + private ObjectId bumpTerm(Repository git, ProposedTimestamp ts, + ObjectInserter inserter) throws IOException { CommitBuilder b = new CommitBuilder(); if (!ObjectId.zeroId().equals(acceptedOldIndex)) { try (RevWalk rw = new RevWalk(git)) { RevCommit c = rw.parseCommit(acceptedOldIndex); + if (getSystem().requireMonotonicLeaderElections()) { + if (ts.read(SECONDS) < c.getCommitTime()) { + throw new TimeIsUncertainException(); + } + } b.setTreeId(c.getTree()); b.setParentId(acceptedOldIndex); term = parseTerm(c.getFooterLines(TERM)) + 1; @@ -116,7 +126,7 @@ class ElectionRound extends Round { msg.append(' ').append(tag); } - b.setAuthor(leader.getSystem().newCommitter()); + b.setAuthor(leader.getSystem().newCommitter(ts)); b.setCommitter(b.getAuthor()); b.setMessage(msg.toString()); @@ -138,4 +148,12 @@ class ElectionRound extends Round { } return Long.parseLong(s, 10); } + + private void blockUntil(ProposedTimestamp ts) throws IOException { + try { + ts.blockUntil(getSystem().getMaxWaitForMonotonicClock()); + } catch (InterruptedException | TimeoutException e) { + throw new TimeIsUncertainException(e); + } + } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/KetchSystem.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/KetchSystem.java index 71e872e3fa..33f526e52c 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/KetchSystem.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/KetchSystem.java @@ -53,6 +53,7 @@ import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_NAME; import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_REMOTE; import java.net.URISyntaxException; +import java.time.Duration; import java.util.ArrayList; import java.util.List; import java.util.Random; @@ -67,6 +68,9 @@ import org.eclipse.jgit.lib.PersonIdent; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.transport.RemoteConfig; import org.eclipse.jgit.transport.URIish; +import org.eclipse.jgit.util.time.MonotonicClock; +import org.eclipse.jgit.util.time.MonotonicSystemClock; +import org.eclipse.jgit.util.time.ProposedTimestamp; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -88,6 +92,7 @@ public class KetchSystem { } private final ScheduledExecutorService executor; + private final MonotonicClock clock; private final String txnNamespace; private final String txnAccepted; private final String txnCommitted; @@ -95,7 +100,7 @@ public class KetchSystem { /** Create a default system with a thread pool of 1 thread per CPU. */ public KetchSystem() { - this(defaultExecutor(), DEFAULT_TXN_NAMESPACE); + this(defaultExecutor(), new MonotonicSystemClock(), DEFAULT_TXN_NAMESPACE); } /** @@ -103,13 +108,17 @@ public class KetchSystem { * * @param executor * thread pool to run background operations. + * @param clock + * clock to create timestamps. * @param txnNamespace * reference namespace for the RefTree graph and associated * transaction state. Must begin with {@code "refs/"} and end * with {@code '/'}, for example {@code "refs/txn/"}. */ - public KetchSystem(ScheduledExecutorService executor, String txnNamespace) { + public KetchSystem(ScheduledExecutorService executor, MonotonicClock clock, + String txnNamespace) { this.executor = executor; + this.clock = clock; this.txnNamespace = txnNamespace; this.txnAccepted = txnNamespace + ACCEPTED; this.txnCommitted = txnNamespace + COMMITTED; @@ -121,6 +130,28 @@ public class KetchSystem { return executor; } + /** @return clock to obtain timestamps from. */ + public MonotonicClock getClock() { + return clock; + } + + /** + * @return how long the leader will wait for the {@link #getClock()}'s + * {@code ProposedTimestamp} used in commits proposed to the RefTree + * graph ({@link #getTxnAccepted()}). Defaults to 5 seconds. + */ + public Duration getMaxWaitForMonotonicClock() { + return Duration.ofSeconds(5); + } + + /** + * @return true if elections should require monotonically increasing commit + * timestamps. This requires a very good {@link MonotonicClock}. + */ + public boolean requireMonotonicLeaderElections() { + return false; + } + /** * Get the namespace used for the RefTree graph and transaction management. * @@ -145,27 +176,32 @@ public class KetchSystem { return txnStage; } - /** @return identity line for the committer header of a RefTreeGraph. */ - public PersonIdent newCommitter() { + /** + * @param time + * timestamp for the committer. + * @return identity line for the committer header of a RefTreeGraph. + */ + public PersonIdent newCommitter(ProposedTimestamp time) { String name = "ketch"; //$NON-NLS-1$ String email = "ketch@system"; //$NON-NLS-1$ - return new PersonIdent(name, email); + return new PersonIdent(name, email, time); } /** * Construct a random tag to identify a candidate during leader election. * <p> * Multiple processes trying to elect themselves leaders at exactly the same - * time (rounded to seconds) using the same {@link #newCommitter()} identity - * strings, for the same term, may generate the same ObjectId for the - * election commit and falsely assume they have both won. + * time (rounded to seconds) using the same + * {@link #newCommitter(ProposedTimestamp)} identity strings, for the same + * term, may generate the same ObjectId for the election commit and falsely + * assume they have both won. * <p> * Candidates add this tag to their election ballot commit to disambiguate * the election. The tag only needs to be unique for a given triplet of - * {@link #newCommitter()}, system time (rounded to seconds), and term. If - * every replica in the system uses a unique {@code newCommitter} (such as - * including the host name after the {@code "@"} in the email address) the - * tag could be the empty string. + * {@link #newCommitter(ProposedTimestamp)}, system time (rounded to + * seconds), and term. If every replica in the system uses a unique + * {@code newCommitter} (such as including the host name after the + * {@code "@"} in the email address) the tag could be the empty string. * <p> * The default implementation generates a few bytes of random data. * diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/LocalReplica.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/LocalReplica.java index e297bca45e..907eecbef4 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/LocalReplica.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/LocalReplica.java @@ -64,6 +64,8 @@ import org.eclipse.jgit.lib.RefDatabase; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.revwalk.RevWalk; import org.eclipse.jgit.transport.ReceiveCommand; +import org.eclipse.jgit.util.time.MonotonicClock; +import org.eclipse.jgit.util.time.ProposedTimestamp; /** Ketch replica running on the same system as the {@link KetchLeader}. */ public class LocalReplica extends KetchReplica { @@ -119,9 +121,11 @@ public class LocalReplica extends KetchReplica { getSystem().getExecutor().execute(new Runnable() { @Override public void run() { - try (Repository git = getLeader().openRepository()) { + MonotonicClock clk = getSystem().getClock(); + try (Repository git = getLeader().openRepository(); + ProposedTimestamp ts = clk.propose()) { try { - update(git, req); + update(git, req, ts); req.done(git); } catch (Throwable err) { req.setException(git, err); @@ -139,8 +143,8 @@ public class LocalReplica extends KetchReplica { throw new IOException(KetchText.get().cannotFetchFromLocalReplica); } - private void update(Repository git, ReplicaPushRequest req) - throws IOException { + private void update(Repository git, ReplicaPushRequest req, + ProposedTimestamp ts) throws IOException { RefDatabase refdb = git.getRefDatabase(); CommitMethod method = getCommitMethod(); @@ -156,7 +160,8 @@ public class LocalReplica extends KetchReplica { } BatchRefUpdate batch = refdb.newBatchUpdate(); - batch.setRefLogIdent(getSystem().newCommitter()); + batch.addProposedTimestamp(ts); + batch.setRefLogIdent(getSystem().newCommitter(ts)); batch.setRefLogMessage("ketch", false); //$NON-NLS-1$ batch.setAllowNonFastForwards(true); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/Proposal.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/Proposal.java index 0876eb5dbd..12d3f4c9c8 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/Proposal.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/Proposal.java @@ -67,6 +67,7 @@ import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.revwalk.RevWalk; import org.eclipse.jgit.transport.PushCertificate; import org.eclipse.jgit.transport.ReceiveCommand; +import org.eclipse.jgit.util.time.ProposedTimestamp; /** * A proposal to be applied in a Ketch system. @@ -123,6 +124,8 @@ public class Proposal { private PersonIdent author; private String message; private PushCertificate pushCert; + + private List<ProposedTimestamp> timestamps; private final List<Runnable> listeners = new CopyOnWriteArrayList<>(); private final AtomicReference<State> state = new AtomicReference<>(NEW); @@ -223,6 +226,31 @@ public class Proposal { } /** + * @return timestamps that Ketch must block for. These may have been used as + * commit times inside the objects involved in the proposal. + */ + public List<ProposedTimestamp> getProposedTimestamps() { + if (timestamps != null) { + return timestamps; + } + return Collections.emptyList(); + } + + /** + * Request the proposal to wait for the affected timestamps to resolve. + * + * @param ts + * @return {@code this}. + */ + public Proposal addProposedTimestamp(ProposedTimestamp ts) { + if (timestamps == null) { + timestamps = new ArrayList<>(4); + } + timestamps.add(ts); + return this; + } + + /** * Add a callback to be invoked when the proposal is done. * <p> * A proposal is done when it has entered either {@link State#EXECUTED} or 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 d34477ab26..ddd7059fc2 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 @@ -46,12 +46,16 @@ package org.eclipse.jgit.internal.ketch; import static org.eclipse.jgit.internal.ketch.Proposal.State.RUNNING; import java.io.IOException; +import java.time.Duration; +import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.TimeoutException; +import java.util.stream.Collectors; import org.eclipse.jgit.annotations.Nullable; import org.eclipse.jgit.internal.storage.reftree.Command; @@ -65,6 +69,7 @@ import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevWalk; import org.eclipse.jgit.transport.ReceiveCommand; +import org.eclipse.jgit.util.time.ProposedTimestamp; /** A {@link Round} that aggregates and sends user {@link Proposal}s. */ class ProposalRound extends Round { @@ -123,8 +128,10 @@ class ProposalRound extends Round { } try { ObjectId id; - try (Repository git = leader.openRepository()) { - id = insertProposals(git); + try (Repository git = leader.openRepository(); + ProposedTimestamp ts = getSystem().getClock().propose()) { + id = insertProposals(git, ts); + blockUntil(ts); } runAsync(id); } catch (NoOp e) { @@ -143,16 +150,16 @@ class ProposalRound extends Round { } } - private ObjectId insertProposals(Repository git) + private ObjectId insertProposals(Repository git, ProposedTimestamp ts) throws IOException, NoOp { ObjectId id; try (ObjectInserter inserter = git.newObjectInserter()) { // TODO(sop) Process signed push certificates. if (queuedTree != null) { - id = insertSingleProposal(git, inserter); + id = insertSingleProposal(git, ts, inserter); } else { - id = insertMultiProposal(git, inserter); + id = insertMultiProposal(git, ts, inserter); } stageCommands = makeStageList(git, inserter); @@ -161,7 +168,7 @@ class ProposalRound extends Round { return id; } - private ObjectId insertSingleProposal(Repository git, + private ObjectId insertSingleProposal(Repository git, ProposedTimestamp ts, ObjectInserter inserter) throws IOException, NoOp { // Fast path: tree is passed in with all proposals applied. ObjectId treeId = queuedTree.writeTree(inserter); @@ -183,13 +190,13 @@ class ProposalRound extends Round { if (!ObjectId.zeroId().equals(acceptedOldIndex)) { b.setParentId(acceptedOldIndex); } - b.setCommitter(leader.getSystem().newCommitter()); + b.setCommitter(leader.getSystem().newCommitter(ts)); b.setAuthor(p.getAuthor() != null ? p.getAuthor() : b.getCommitter()); b.setMessage(message(p)); return inserter.insert(b); } - private ObjectId insertMultiProposal(Repository git, + private ObjectId insertMultiProposal(Repository git, ProposedTimestamp ts, ObjectInserter inserter) throws IOException, NoOp { // The tree was not passed in, or there are multiple proposals // each needing their own commit. Reset the tree and replay each @@ -208,7 +215,7 @@ class ProposalRound extends Round { } } - PersonIdent committer = leader.getSystem().newCommitter(); + PersonIdent committer = leader.getSystem().newCommitter(ts); for (Proposal p : todo) { if (!tree.apply(p.getCommands())) { // This should not occur, previously during queuing the @@ -292,6 +299,20 @@ class ProposalRound extends Round { return b.makeStageList(newObjs, git, inserter); } + private void blockUntil(ProposedTimestamp ts) + throws TimeIsUncertainException { + List<ProposedTimestamp> times = todo.stream() + .flatMap(p -> p.getProposedTimestamps().stream()) + .collect(Collectors.toCollection(ArrayList::new)); + times.add(ts); + + try { + Duration maxWait = getSystem().getMaxWaitForMonotonicClock(); + ProposedTimestamp.blockUntil(times, maxWait); + } catch (InterruptedException | TimeoutException e) { + throw new TimeIsUncertainException(e); + } + } private static class NoOp extends Exception { private static final long serialVersionUID = 1L; 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 6f4a178673..396fbdd722 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 @@ -44,13 +44,13 @@ package org.eclipse.jgit.internal.ketch; import static org.eclipse.jgit.internal.ketch.KetchReplica.CommitMethod.ALL_REFS; +import static org.eclipse.jgit.lib.Ref.Storage.NETWORK; import static org.eclipse.jgit.transport.ReceiveCommand.Result.LOCK_FAILURE; import static org.eclipse.jgit.transport.ReceiveCommand.Result.NOT_ATTEMPTED; import static org.eclipse.jgit.transport.ReceiveCommand.Result.OK; import static org.eclipse.jgit.transport.ReceiveCommand.Result.REJECTED_NODELETE; import static org.eclipse.jgit.transport.ReceiveCommand.Result.REJECTED_NONFASTFORWARD; import static org.eclipse.jgit.transport.ReceiveCommand.Result.REJECTED_OTHER_REASON; -import static org.eclipse.jgit.lib.Ref.Storage.NETWORK; import java.io.IOException; import java.util.ArrayList; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/Round.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/Round.java index 1335b85cca..dd8e568c7f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/Round.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/Round.java @@ -75,6 +75,10 @@ abstract class Round { this.acceptedOldIndex = head; } + KetchSystem getSystem() { + return leader.getSystem(); + } + /** * Creates a commit for {@code refs/txn/accepted} and calls * {@link #runAsync(AnyObjectId)} to begin execution of the round across diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/TimeIsUncertainException.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/TimeIsUncertainException.java new file mode 100644 index 0000000000..7223f553ca --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/TimeIsUncertainException.java @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2016, 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.ketch; + +import java.io.IOException; + +import org.eclipse.jgit.internal.JGitText; + +class TimeIsUncertainException extends IOException { + private static final long serialVersionUID = 1L; + + TimeIsUncertainException() { + super(JGitText.get().timeIsUncertain); + } + + TimeIsUncertainException(Exception e) { + super(JGitText.get().timeIsUncertain, e); + } +} 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 ecd4b23c25..f7decf1324 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 @@ -145,6 +145,8 @@ public final class DfsBlockCache { * <p> * If a pack file has a native size, a whole multiple of the native size * will be used until it matches this size. + * <p> + * The value for blockSize must be a power of 2. */ private final int blockSize; @@ -175,13 +177,14 @@ public final class DfsBlockCache { /** Number of bytes currently loaded in the cache. */ private volatile long liveBytes; + @SuppressWarnings("unchecked") private DfsBlockCache(final DfsBlockCacheConfig cfg) { tableSize = tableSize(cfg); if (tableSize < 1) throw new IllegalArgumentException(JGitText.get().tSizeMustBeGreaterOrEqual1); table = new AtomicReferenceArray<HashEntry>(tableSize); - loadLocks = new ReentrantLock[32]; + loadLocks = new ReentrantLock[cfg.getConcurrencyLevel()]; for (int i = 0; i < loadLocks.length; i++) loadLocks[i] = new ReentrantLock(true /* fair */); @@ -260,20 +263,22 @@ public final class DfsBlockCache { // TODO This table grows without bound. It needs to clean up // entries that aren't in cache anymore, and aren't being used // by a live DfsObjDatabase reference. - synchronized (packCache) { - DfsPackFile pack = packCache.get(dsc); - if (pack != null && pack.invalid()) { - packCache.remove(dsc); - pack = null; - } - if (pack == null) { - if (key == null) - key = new DfsPackKey(); - pack = new DfsPackFile(this, dsc, key); - packCache.put(dsc, pack); - } + + DfsPackFile pack = packCache.get(dsc); + if (pack != null && !pack.invalid()) { return pack; } + + // 'pack' either didn't exist or was invalid. Compute a new + // entry atomically (guaranteed by ConcurrentHashMap). + return packCache.compute(dsc, (k, v) -> { + if (v != null && !v.invalid()) { // valid value added by + return v; // another thread + } else { + return new DfsPackFile( + this, dsc, key != null ? key : new DfsPackKey()); + } + }); } private int hash(int packHash, long off) { @@ -416,6 +421,7 @@ public final class DfsBlockCache { clockLock.unlock(); } + @SuppressWarnings("unchecked") private void addToClock(Ref ref, int credit) { clockLock.lock(); try { @@ -500,9 +506,7 @@ public final class DfsBlockCache { } void remove(DfsPackFile pack) { - synchronized (packCache) { - packCache.remove(pack.getPackDescription()); - } + packCache.remove(pack.getPackDescription()); } private int slot(DfsPackKey pack, long position) { 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 a7d13defdc..089bfa471d 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 @@ -47,6 +47,7 @@ import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_CORE_SECTION; import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_DFS_SECTION; import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_BLOCK_LIMIT; import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_BLOCK_SIZE; +import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_CONCURRENCY_LEVEL; import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_STREAM_RATIO; import java.text.MessageFormat; @@ -65,12 +66,14 @@ public class DfsBlockCacheConfig { private long blockLimit; private int blockSize; private double streamRatio; + private int concurrencyLevel; /** Create a default configuration. */ public DfsBlockCacheConfig() { setBlockLimit(32 * MB); setBlockSize(64 * KB); setStreamRatio(0.30); + setConcurrencyLevel(32); } /** @@ -103,10 +106,38 @@ public class DfsBlockCacheConfig { /** * @param newSize * size in bytes of a single window read in from the pack file. + * The value must be a power of 2. * @return {@code this} */ public DfsBlockCacheConfig setBlockSize(final int newSize) { - blockSize = Math.max(512, newSize); + int size = Math.max(512, newSize); + if ((size & (size - 1)) != 0) { + throw new IllegalArgumentException( + JGitText.get().blockSizeNotPowerOf2); + } + blockSize = size; + return this; + } + + /** + * @return the estimated number of threads concurrently accessing the cache. + * <b>Default is 32.</b> + * @since 4.6 + */ + public int getConcurrencyLevel() { + return concurrencyLevel; + } + + /** + * @param newConcurrencyLevel + * the estimated number of threads concurrently accessing the + * cache. + * @return {@code this} + * @since 4.6 + */ + public DfsBlockCacheConfig setConcurrencyLevel( + final int newConcurrencyLevel) { + concurrencyLevel = newConcurrencyLevel; return this; } @@ -154,6 +185,12 @@ public class DfsBlockCacheConfig { CONFIG_KEY_BLOCK_SIZE, getBlockSize())); + setConcurrencyLevel(rc.getInt( + CONFIG_CORE_SECTION, + CONFIG_DFS_SECTION, + CONFIG_KEY_CONCURRENCY_LEVEL, + getConcurrencyLevel())); + String v = rc.getString( CONFIG_CORE_SECTION, CONFIG_DFS_SECTION, 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 a5e920a75e..c179e77786 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 @@ -312,8 +312,7 @@ public class DfsInserter extends ObjectInserter { } DfsOutputStream os = db.writeFile(pack, INDEX); - try { - CountingOutputStream cnt = new CountingOutputStream(os); + try (CountingOutputStream cnt = new CountingOutputStream(os)) { if (buf != null) buf.writeTo(cnt, null); else @@ -321,7 +320,9 @@ public class DfsInserter extends ObjectInserter { pack.addFileExt(INDEX); pack.setFileSize(INDEX, cnt.getCount()); } finally { - os.close(); + if (buf != null) { + buf.close(); + } } return packIndex; } 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 2f61dea0d5..8c9329503f 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 @@ -113,6 +113,7 @@ public final class DfsReader extends ObjectReader implements ObjectReuseAsIs { DfsReader(DfsObjDatabase db) { this.db = db; + this.streamFileThreshold = db.getReaderOptions().getStreamFileThreshold(); } DfsReaderOptions getOptions() { @@ -125,10 +126,6 @@ public final class DfsReader extends ObjectReader implements ObjectReuseAsIs { return baseCache; } - int getStreamFileThreshold() { - return getOptions().getStreamFileThreshold(); - } - @Override public ObjectReader newReader() { return new DfsReader(db); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRefUpdate.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRefUpdate.java index d872f973c4..1f26fe35ff 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRefUpdate.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsRefUpdate.java @@ -47,9 +47,9 @@ import java.io.IOException; import org.eclipse.jgit.lib.ObjectIdRef; import org.eclipse.jgit.lib.Ref; +import org.eclipse.jgit.lib.Ref.Storage; import org.eclipse.jgit.lib.RefUpdate; import org.eclipse.jgit.lib.SymbolicRef; -import org.eclipse.jgit.lib.Ref.Storage; import org.eclipse.jgit.revwalk.RevObject; import org.eclipse.jgit.revwalk.RevTag; import org.eclipse.jgit.revwalk.RevWalk; 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 6f390a4b3b..fd213977a8 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 @@ -16,6 +16,7 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; +import org.eclipse.jgit.annotations.Nullable; import org.eclipse.jgit.internal.storage.pack.PackExt; import org.eclipse.jgit.lib.BatchRefUpdate; import org.eclipse.jgit.lib.ObjectId; @@ -54,6 +55,7 @@ public class InMemoryRepository extends DfsRepository { private final DfsObjDatabase objdb; private final RefDatabase refdb; + private String gitwebDescription; private boolean performsAtomicTransactions = true; /** @@ -94,6 +96,17 @@ public class InMemoryRepository extends DfsRepository { performsAtomicTransactions = atomic; } + @Override + @Nullable + public String getGitwebDescription() { + return gitwebDescription; + } + + @Override + public void setGitwebDescription(@Nullable String d) { + gitwebDescription = d; + } + private class MemObjDatabase extends DfsObjDatabase { private List<DfsPackDescription> packs = new ArrayList<DfsPackDescription>(); 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 3c101e621a..30e973ecf4 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 @@ -43,11 +43,11 @@ package org.eclipse.jgit.internal.storage.file; -import com.googlecode.javaewah.EWAHCompressedBitmap; - import org.eclipse.jgit.lib.AnyObjectId; import org.eclipse.jgit.lib.ObjectIdOwnerMap; +import com.googlecode.javaewah.EWAHCompressedBitmap; + /** * Base implementation of the PackBitmapIndex. */ diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/BitSet.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/BitSet.java index ddb5ff0cac..bafae87cd8 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/BitSet.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/BitSet.java @@ -96,7 +96,7 @@ final class BitSet { } if (lastNonEmptyWord != 0) - compressed.add(lastNonEmptyWord); + compressed.addWord(lastNonEmptyWord); if (runningEmptyWords > 0) { compressed.addStreamOfEmptyWords(false, runningEmptyWords); @@ -107,7 +107,7 @@ final class BitSet { } int bitsThatMatter = 64 - Long.numberOfLeadingZeros(lastNonEmptyWord); if (bitsThatMatter > 0) - compressed.add(lastNonEmptyWord, bitsThatMatter); + compressed.addWord(lastNonEmptyWord, bitsThatMatter); return compressed; } 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 b27bcc4258..b18a06f9c9 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 @@ -47,9 +47,6 @@ import java.text.MessageFormat; import java.util.Iterator; import java.util.NoSuchElementException; -import com.googlecode.javaewah.EWAHCompressedBitmap; -import com.googlecode.javaewah.IntIterator; - import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.lib.AnyObjectId; import org.eclipse.jgit.lib.BitmapIndex; @@ -59,6 +56,9 @@ import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectIdOwnerMap; import org.eclipse.jgit.util.BlockList; +import com.googlecode.javaewah.EWAHCompressedBitmap; +import com.googlecode.javaewah.IntIterator; + /** A compressed bitmap representation of the entire object graph. */ public class BitmapIndexImpl implements BitmapIndex { private static final int EXTRA_BITS = 10 * 1024; @@ -504,10 +504,10 @@ public class BitmapIndexImpl implements BitmapIndex { static final EWAHCompressedBitmap ones(int sizeInBits) { EWAHCompressedBitmap mask = new EWAHCompressedBitmap(); mask.addStreamOfEmptyWords( - true, sizeInBits / EWAHCompressedBitmap.wordinbits); - int remaining = sizeInBits % EWAHCompressedBitmap.wordinbits; + true, sizeInBits / EWAHCompressedBitmap.WORD_IN_BITS); + int remaining = sizeInBits % EWAHCompressedBitmap.WORD_IN_BITS; if (remaining > 0) - mask.add((1L << remaining) - 1, remaining); + mask.addWord((1L << remaining) - 1, remaining); return mask; } } 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 53fd37e534..0388acbbaf 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 @@ -53,9 +53,13 @@ import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.text.MessageFormat; +import java.text.ParseException; import java.util.HashSet; +import java.util.Objects; import java.util.Set; +import org.eclipse.jgit.annotations.Nullable; +import org.eclipse.jgit.api.errors.JGitInternalException; import org.eclipse.jgit.attributes.AttributesNode; import org.eclipse.jgit.attributes.AttributesNodeProvider; import org.eclipse.jgit.errors.ConfigInvalidException; @@ -63,15 +67,16 @@ import org.eclipse.jgit.events.ConfigChangedEvent; import org.eclipse.jgit.events.ConfigChangedListener; import org.eclipse.jgit.events.IndexChangedEvent; import org.eclipse.jgit.internal.JGitText; -import org.eclipse.jgit.internal.storage.reftree.RefTreeDatabase; import org.eclipse.jgit.internal.storage.file.ObjectDirectory.AlternateHandle; import org.eclipse.jgit.internal.storage.file.ObjectDirectory.AlternateRepository; +import org.eclipse.jgit.internal.storage.reftree.RefTreeDatabase; import org.eclipse.jgit.lib.BaseRepositoryBuilder; import org.eclipse.jgit.lib.ConfigConstants; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.CoreConfig.HideDotFiles; import org.eclipse.jgit.lib.CoreConfig.SymLinks; import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.lib.ProgressMonitor; import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.RefDatabase; import org.eclipse.jgit.lib.RefUpdate; @@ -79,8 +84,11 @@ import org.eclipse.jgit.lib.ReflogReader; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.storage.file.FileBasedConfig; import org.eclipse.jgit.storage.file.FileRepositoryBuilder; +import org.eclipse.jgit.storage.pack.PackConfig; import org.eclipse.jgit.util.FS; import org.eclipse.jgit.util.FileUtils; +import org.eclipse.jgit.util.IO; +import org.eclipse.jgit.util.RawParseUtils; import org.eclipse.jgit.util.StringUtils; import org.eclipse.jgit.util.SystemReader; @@ -110,16 +118,13 @@ import org.eclipse.jgit.util.SystemReader; * */ public class FileRepository extends Repository { - private final FileBasedConfig systemConfig; + private static final String UNNAMED = "Unnamed repository; edit this file to name it for gitweb."; //$NON-NLS-1$ + private final FileBasedConfig systemConfig; private final FileBasedConfig userConfig; - private final FileBasedConfig repoConfig; - private final RefDatabase refs; - private final ObjectDirectory objectDatabase; - private FileSnapshot snapshot; /** @@ -177,10 +182,12 @@ public class FileRepository extends Repository { getFS()); else systemConfig = new FileBasedConfig(null, FS.DETECTED) { + @Override public void load() { // empty, do not load } + @Override public boolean isOutdated() { // regular class would bomb here return false; @@ -197,6 +204,7 @@ public class FileRepository extends Repository { loadRepoConfig(); repoConfig.addChangeListener(new ConfigChangedListener() { + @Override public void onConfigChanged(ConfigChangedEvent event) { fireEvent(event); } @@ -279,6 +287,7 @@ public class FileRepository extends Repository { * @throws IOException * in case of IO problem */ + @Override public void create(boolean bare) throws IOException { final FileBasedConfig cfg = getConfig(); if (cfg.getFile().exists()) { @@ -376,21 +385,20 @@ public class FileRepository extends Repository { return objectDatabase.getDirectory(); } - /** - * @return the object database which stores this repository's data. - */ + /** @return the object database storing this repository's data. */ + @Override public ObjectDirectory getObjectDatabase() { return objectDatabase; } /** @return the reference database which stores the reference namespace. */ + @Override public RefDatabase getRefDatabase() { return refs; } - /** - * @return the configuration of this repository - */ + /** @return the configuration of this repository. */ + @Override public FileBasedConfig getConfig() { if (systemConfig.isOutdated()) { try { @@ -416,6 +424,59 @@ public class FileRepository extends Repository { return repoConfig; } + @Override + @Nullable + public String getGitwebDescription() throws IOException { + String d; + try { + d = RawParseUtils.decode(IO.readFully(descriptionFile())); + } catch (FileNotFoundException err) { + return null; + } + if (d != null) { + d = d.trim(); + if (d.isEmpty() || UNNAMED.equals(d)) { + return null; + } + } + return d; + } + + @Override + public void setGitwebDescription(@Nullable String description) + throws IOException { + String old = getGitwebDescription(); + if (Objects.equals(old, description)) { + return; + } + + File path = descriptionFile(); + LockFile lock = new LockFile(path); + if (!lock.lock()) { + throw new IOException(MessageFormat.format(JGitText.get().lockError, + path.getAbsolutePath())); + } + try { + String d = description; + if (d != null) { + d = d.trim(); + if (!d.isEmpty()) { + d += '\n'; + } + } else { + d = ""; //$NON-NLS-1$ + } + lock.write(Constants.encode(d)); + lock.commit(); + } finally { + lock.unlock(); + } + } + + private File descriptionFile() { + return new File(getDirectory(), "description"); //$NON-NLS-1$ + } + /** * Objects known to exist but not expressed by {@link #getAllRefs()}. * <p> @@ -426,6 +487,7 @@ public class FileRepository extends Repository { * * @return unmodifiable collection of other known objects. */ + @Override public Set<ObjectId> getAdditionalHaves() { HashSet<ObjectId> r = new HashSet<ObjectId>(); for (AlternateHandle d : objectDatabase.myAlternates()) { @@ -464,9 +526,7 @@ public class FileRepository extends Repository { detectIndexChanges(); } - /** - * Detect index changes. - */ + /** Detect index changes. */ private void detectIndexChanges() { if (isBare()) return; @@ -490,6 +550,7 @@ public class FileRepository extends Repository { * named ref does not exist. * @throws IOException the ref could not be accessed. */ + @Override public ReflogReader getReflogReader(String refName) throws IOException { Ref ref = findRef(refName); if (ref != null) @@ -527,6 +588,7 @@ public class FileRepository extends Repository { globalAttributesNode = new GlobalAttributesNode(repo); } + @Override public AttributesNode getInfoAttributesNode() throws IOException { if (infoAttributesNode instanceof InfoAttributesNode) infoAttributesNode = ((InfoAttributesNode) infoAttributesNode) @@ -534,6 +596,7 @@ public class FileRepository extends Repository { return infoAttributesNode; } + @Override public AttributesNode getGlobalAttributesNode() throws IOException { if (globalAttributesNode instanceof GlobalAttributesNode) globalAttributesNode = ((GlobalAttributesNode) globalAttributesNode) @@ -555,4 +618,16 @@ public class FileRepository extends Repository { } + @Override + public void autoGC(ProgressMonitor monitor) { + GC gc = new GC(this); + gc.setPackConfig(new PackConfig(this)); + gc.setProgressMonitor(monitor); + gc.setAuto(true); + try { + gc.gc(); + } catch (ParseException | IOException e) { + throw new JGitInternalException(JGitText.get().gcFailed, e); + } + } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileSnapshot.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileSnapshot.java index 8926d79306..97f3b573d0 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileSnapshot.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/FileSnapshot.java @@ -264,12 +264,6 @@ public class FileSnapshot { return false; } - // Our lastRead flag may be old, refresh and retry - lastRead = System.currentTimeMillis(); - if (notRacyClean(lastRead)) { - return false; - } - // We last read this path too close to its last observed // modification time. We may have missed a modification. // Scan again, to ensure we still see the same state. 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 a3e9430b13..b608416868 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 @@ -52,6 +52,10 @@ import java.io.IOException; import java.io.OutputStream; import java.nio.channels.Channels; import java.nio.channels.FileChannel; +import java.nio.file.DirectoryStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.nio.file.StandardCopyOption; import java.text.MessageFormat; import java.text.ParseException; @@ -62,12 +66,16 @@ import java.util.Comparator; import java.util.Date; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.TreeMap; +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; @@ -100,6 +108,8 @@ import org.eclipse.jgit.treewalk.filter.TreeFilter; import org.eclipse.jgit.util.FileUtils; import org.eclipse.jgit.util.GitDateParser; import org.eclipse.jgit.util.SystemReader; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * A garbage collector for git {@link FileRepository}. Instances of this class @@ -109,10 +119,27 @@ import org.eclipse.jgit.util.SystemReader; * adapted to FileRepositories. */ public class GC { + private final static Logger LOG = LoggerFactory + .getLogger(GC.class); + private static final String PRUNE_EXPIRE_DEFAULT = "2.weeks.ago"; //$NON-NLS-1$ private static final String PRUNE_PACK_EXPIRE_DEFAULT = "1.hour.ago"; //$NON-NLS-1$ + private static final Pattern PATTERN_LOOSE_OBJECT = Pattern + .compile("[0-9a-fA-F]{38}"); //$NON-NLS-1$ + + private static final String PACK_EXT = "." + PackExt.PACK.getExtension();//$NON-NLS-1$ + + private static final String BITMAP_EXT = "." //$NON-NLS-1$ + + PackExt.BITMAP_INDEX.getExtension(); + + private static final String INDEX_EXT = "." + PackExt.INDEX.getExtension(); //$NON-NLS-1$ + + private static final int DEFAULT_AUTOPACKLIMIT = 50; + + private static final int DEFAULT_AUTOLIMIT = 6700; + private final FileRepository repo; private ProgressMonitor pm; @@ -143,6 +170,11 @@ public class GC { private long lastRepackTime; /** + * Whether gc should do automatic housekeeping + */ + private boolean automatic; + + /** * Creates a new garbage collector with default values. An expirationTime of * two weeks and <code>null</code> as progress monitor will be used. * @@ -163,6 +195,10 @@ public class GC { * <li>prune all loose objects which are now reachable by packs</li> * </ul> * + * If {@link #setAuto(boolean)} was set to {@code true} {@code gc} will + * first check whether any housekeeping is required; if not, it exits + * without performing any work. + * * @return the collection of {@link PackFile}'s which are newly created * @throws IOException * @throws ParseException @@ -170,6 +206,9 @@ public class GC { * parsed */ public Collection<PackFile> gc() throws IOException, ParseException { + if (automatic && !needGc()) { + return Collections.emptyList(); + } pm.start(6 /* tasks */); packRefs(); // TODO: implement reflog_expire(pm, repo); @@ -325,45 +364,48 @@ public class GC { Set<ObjectId> indexObjects = null; File objects = repo.getObjectsDirectory(); String[] fanout = objects.list(); - if (fanout != null && fanout.length > 0) { - pm.beginTask(JGitText.get().pruneLooseUnreferencedObjects, - fanout.length); - try { - for (String d : fanout) { - pm.update(1); - if (d.length() != 2) + if (fanout == null || fanout.length == 0) { + return; + } + pm.beginTask(JGitText.get().pruneLooseUnreferencedObjects, + fanout.length); + try { + for (String d : fanout) { + pm.update(1); + if (d.length() != 2) + continue; + File[] entries = new File(objects, d).listFiles(); + if (entries == null) + continue; + for (File f : entries) { + String fName = f.getName(); + if (fName.length() != Constants.OBJECT_ID_STRING_LENGTH - 2) continue; - File[] entries = new File(objects, d).listFiles(); - if (entries == null) + if (repo.getFS().lastModified(f) >= expireDate) continue; - for (File f : entries) { - String fName = f.getName(); - if (fName.length() != Constants.OBJECT_ID_STRING_LENGTH - 2) - continue; - if (repo.getFS().lastModified(f) >= expireDate) + try { + ObjectId id = ObjectId.fromString(d + fName); + if (objectsToKeep.contains(id)) continue; - try { - ObjectId id = ObjectId.fromString(d + fName); - if (objectsToKeep.contains(id)) - continue; - if (indexObjects == null) - indexObjects = listNonHEADIndexObjects(); - if (indexObjects.contains(id)) - continue; - deletionCandidates.put(id, f); - } catch (IllegalArgumentException notAnObject) { - // ignoring the file that does not represent loose - // object + if (indexObjects == null) + indexObjects = listNonHEADIndexObjects(); + if (indexObjects.contains(id)) continue; - } + deletionCandidates.put(id, f); + } catch (IllegalArgumentException notAnObject) { + // ignoring the file that does not represent loose + // object + continue; } } - } finally { - pm.endTask(); } + } finally { + pm.endTask(); } - if (deletionCandidates.isEmpty()) + + if (deletionCandidates.isEmpty()) { return; + } // From the set of current refs remove all those which have been handled // during last repack(). Only those refs will survive which have been @@ -433,12 +475,19 @@ public class GC { // loose objects. Make a last check, though, to avoid deleting objects // that could have been referenced while the candidates list was being // built (by an incoming push, for example). + Set<File> touchedFanout = new HashSet<>(); for (File f : deletionCandidates.values()) { if (f.lastModified() < expireDate) { f.delete(); + touchedFanout.add(f.getParentFile()); } } + for (File f : touchedFanout) { + FileUtils.delete(f, + FileUtils.EMPTY_DIRECTORIES_ONLY | FileUtils.IGNORE_ERRORS); + } + repo.getObjectDatabase().close(); } @@ -625,6 +674,7 @@ public class GC { throw new IOException(e); } prunePacked(); + deleteOrphans(); lastPackedRefs = refsBefore; lastRepackTime = time; @@ -632,6 +682,48 @@ public class GC { } /** + * Deletes orphans + * <p> + * A file is considered an orphan if it is either a "bitmap" or an index + * file, and its corresponding pack file is missing in the list. + * </p> + */ + private void deleteOrphans() { + Path packDir = Paths.get(repo.getObjectsDirectory().getAbsolutePath(), + "pack"); //$NON-NLS-1$ + List<String> fileNames = null; + try (Stream<Path> files = Files.list(packDir)) { + fileNames = files.map(path -> path.getFileName().toString()) + .filter(name -> { + return (name.endsWith(PACK_EXT) + || name.endsWith(BITMAP_EXT) + || name.endsWith(INDEX_EXT)); + }).sorted(Collections.reverseOrder()) + .collect(Collectors.toList()); + } catch (IOException e1) { + // ignore + } + if (fileNames == null) { + return; + } + + String base = null; + for (String n : fileNames) { + if (n.endsWith(PACK_EXT)) { + base = n.substring(0, n.lastIndexOf('.')); + } else { + if (base == null || !n.startsWith(base)) { + try { + Files.delete(new File(packDir.toFile(), n).toPath()); + } catch (IOException e) { + LOG.error(e.getMessage(), e); + } + } + } + } + } + + /** * @param ref * the ref which log should be inspected * @param minTime only reflog entries not older then this time are processed @@ -1081,4 +1173,114 @@ public class GC { this.packExpire = packExpire; packExpireAgeMillis = -1; } + + /** + * Set the {@code gc --auto} option. + * + * With this option, gc checks whether any housekeeping is required; if not, + * it exits without performing any work. Some JGit commands run + * {@code gc --auto} after performing operations that could create many + * loose objects. + * <p/> + * Housekeeping is required if there are too many loose objects or too many + * packs in the repository. If the number of loose objects exceeds the value + * of the gc.auto option JGit GC consolidates all existing packs into a + * single pack (equivalent to {@code -A} option), whereas git-core would + * combine all loose objects into a single pack using {@code repack -d -l}. + * Setting the value of {@code gc.auto} to 0 disables automatic packing of + * loose objects. + * <p/> + * If the number of packs exceeds the value of {@code gc.autoPackLimit}, + * then existing packs (except those marked with a .keep file) are + * consolidated into a single pack by using the {@code -A} option of repack. + * Setting {@code gc.autoPackLimit} to 0 disables automatic consolidation of + * packs. + * <p/> + * Like git the following jgit commands run auto gc: + * <ul> + * <li>fetch</li> + * <li>merge</li> + * <li>rebase</li> + * <li>receive-pack</li> + * </ul> + * The auto gc for receive-pack can be suppressed by setting the config + * option {@code receive.autogc = false} + * + * @param auto + * defines whether gc should do automatic housekeeping + * @since 4.5 + */ + public void setAuto(boolean auto) { + this.automatic = auto; + } + + private boolean needGc() { + if (tooManyPacks()) { + addRepackAllOption(); + } else if (!tooManyLooseObjects()) { + return false; + } + // TODO run pre-auto-gc hook, if it fails return false + return true; + } + + private void addRepackAllOption() { + // TODO: if JGit GC is enhanced to support repack's option -l this + // method needs to be implemented + } + + /** + * @return {@code true} if number of packs > gc.autopacklimit (default 50) + */ + boolean tooManyPacks() { + int autopacklimit = repo.getConfig().getInt( + ConfigConstants.CONFIG_GC_SECTION, + ConfigConstants.CONFIG_KEY_AUTOPACKLIMIT, + DEFAULT_AUTOPACKLIMIT); + if (autopacklimit <= 0) { + return false; + } + // JGit always creates two packfiles, one for the objects reachable from + // branches, and another one for the rest + return repo.getObjectDatabase().getPacks().size() > (autopacklimit + 1); + } + + /** + * Quickly estimate number of loose objects, SHA1 is distributed evenly so + * counting objects in one directory (bucket 17) is sufficient + * + * @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); + if (auto <= 0) { + return false; + } + int n = 0; + int threshold = (auto + 255) / 256; + Path dir = repo.getObjectsDirectory().toPath().resolve("17"); //$NON-NLS-1$ + if (!Files.exists(dir)) { + return false; + } + try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir, + new DirectoryStream.Filter<Path>() { + + public boolean accept(Path file) throws IOException { + return Files.isRegularFile(file) && PATTERN_LOOSE_OBJECT + .matcher(file.getFileName().toString()) + .matches(); + } + })) { + for (Iterator<Path> iter = stream.iterator(); iter.hasNext(); + iter.next()) { + if (++n > threshold) { + return true; + } + } + } catch (IOException e) { + LOG.error(e.getMessage(), e); + } + return false; + } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndex.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndex.java index e743cb4aff..7fb8e6d644 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndex.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndex.java @@ -49,13 +49,13 @@ import java.io.IOException; import java.io.InputStream; import java.text.MessageFormat; -import com.googlecode.javaewah.EWAHCompressedBitmap; - import org.eclipse.jgit.errors.CorruptObjectException; import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.lib.AnyObjectId; import org.eclipse.jgit.lib.ObjectId; +import com.googlecode.javaewah.EWAHCompressedBitmap; + /** * Logical representation of the bitmap data stored in the pack index. * {@link ObjectId}s are encoded as a single integer in the range [0, 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 4ff09a148f..956e8de0a7 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 @@ -50,8 +50,6 @@ import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; -import com.googlecode.javaewah.EWAHCompressedBitmap; - import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.internal.storage.file.BitmapIndexImpl.CompressedBitmap; import org.eclipse.jgit.internal.storage.pack.ObjectToPack; @@ -63,6 +61,8 @@ import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectIdOwnerMap; import org.eclipse.jgit.util.BlockList; +import com.googlecode.javaewah.EWAHCompressedBitmap; + /** * Helper for constructing {@link PackBitmapIndex}es. */ 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 7cd68b625e..2c462a78b7 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 @@ -47,15 +47,15 @@ import java.util.Collections; import java.util.Iterator; import java.util.NoSuchElementException; -import com.googlecode.javaewah.EWAHCompressedBitmap; -import com.googlecode.javaewah.IntIterator; - import org.eclipse.jgit.internal.storage.file.BasePackBitmapIndex.StoredBitmap; import org.eclipse.jgit.lib.AnyObjectId; import org.eclipse.jgit.lib.BitmapIndex; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectIdOwnerMap; +import com.googlecode.javaewah.EWAHCompressedBitmap; +import com.googlecode.javaewah.IntIterator; + /** * A PackBitmapIndex that remaps the bitmaps in the previous index to the * positions in the new pack index. Note, unlike typical PackBitmapIndex diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndexV1.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndexV1.java index a7ab00db2d..9d2c70b4c6 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndexV1.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndexV1.java @@ -49,8 +49,6 @@ import java.io.InputStream; import java.text.MessageFormat; import java.util.Arrays; -import com.googlecode.javaewah.EWAHCompressedBitmap; - import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.lib.AnyObjectId; import org.eclipse.jgit.lib.Constants; @@ -59,6 +57,8 @@ import org.eclipse.jgit.lib.ObjectIdOwnerMap; import org.eclipse.jgit.util.IO; import org.eclipse.jgit.util.NB; +import com.googlecode.javaewah.EWAHCompressedBitmap; + /** * Support for the pack bitmap index v1 format. * diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndexWriterV1.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndexWriterV1.java index 8325e2ebd1..f8f02e95e3 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndexWriterV1.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackBitmapIndexWriterV1.java @@ -50,12 +50,11 @@ import java.io.OutputStream; import java.security.DigestOutputStream; import java.text.MessageFormat; -import com.googlecode.javaewah.EWAHCompressedBitmap; - import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.internal.storage.file.PackBitmapIndexBuilder.StoredEntry; import org.eclipse.jgit.lib.Constants; -import org.eclipse.jgit.util.io.SafeBufferedOutputStream; + +import com.googlecode.javaewah.EWAHCompressedBitmap; /** * Creates the version 1 pack bitmap index files. @@ -74,7 +73,7 @@ public class PackBitmapIndexWriterV1 { */ public PackBitmapIndexWriterV1(final OutputStream dst) { out = new DigestOutputStream(dst instanceof BufferedOutputStream ? dst - : new SafeBufferedOutputStream(dst), + : new BufferedOutputStream(dst), Constants.newMessageDigest()); dataOutput = new SimpleDataOutput(out); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndexWriter.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndexWriter.java index 6dfe74bf83..51539112e7 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndexWriter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/PackIndexWriter.java @@ -56,7 +56,6 @@ import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.transport.PackedObjectInfo; import org.eclipse.jgit.util.NB; -import org.eclipse.jgit.util.io.SafeBufferedOutputStream; /** * Creates a table of contents to support random access by {@link PackFile}. @@ -183,7 +182,7 @@ public abstract class PackIndexWriter { */ protected PackIndexWriter(final OutputStream dst) { out = new DigestOutputStream(dst instanceof BufferedOutputStream ? dst - : new SafeBufferedOutputStream(dst), + : new BufferedOutputStream(dst), Constants.newMessageDigest()); tmp = new byte[4 + Constants.OBJECT_ID_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 108065913a..e3d0d6162c 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 @@ -843,6 +843,11 @@ public class RefDirectory extends RefDatabase { } int sp = p.indexOf(' '); + if (sp < 0) { + throw new IOException(MessageFormat.format( + JGitText.get().packedRefsCorruptionDetected, + packedRefsFile.getAbsolutePath())); + } ObjectId id = ObjectId.fromString(p.substring(0, sp)); String name = copy(p, sp + 1, p.length()); ObjectIdRef cur; 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 a2c0561ae1..a742d1747e 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 @@ -94,12 +94,14 @@ final class WindowCursor extends ObjectReader implements ObjectReuseAsIs { WindowCursor(FileObjectDatabase db) { this.db = db; this.createdFromInserter = null; + this.streamFileThreshold = WindowCache.getStreamFileThreshold(); } WindowCursor(FileObjectDatabase db, @Nullable ObjectDirectoryInserter createdFromInserter) { this.db = db; this.createdFromInserter = createdFromInserter; + this.streamFileThreshold = WindowCache.getStreamFileThreshold(); } DeltaBaseCache getDeltaBaseCache() { @@ -337,10 +339,6 @@ final class WindowCursor extends ObjectReader implements ObjectReuseAsIs { } } - int getStreamFileThreshold() { - return WindowCache.getStreamFileThreshold(); - } - @Override @Nullable public ObjectInserter getCreatedFromInserter() { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackOutputStream.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackOutputStream.java index be1e3d4715..59166e6206 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackOutputStream.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackOutputStream.java @@ -183,7 +183,7 @@ public final class PackOutputStream extends OutputStream { public final void writeHeader(ObjectToPack otp, long rawLength) throws IOException { ObjectToPack b = otp.getDeltaBase(); - if (b != null && (b.isWritten() & ofsDelta)) { + if (b != null && (b.isWritten() & ofsDelta)) { // Non-short-circuit logic is intentional int n = objectHeader(rawLength, OBJ_OFS_DELTA, headerBuffer); n = ofsDelta(count - b.getOffset(), headerBuffer, n); write(headerBuffer, 0, n); 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 691867aba8..8b4d2e6d35 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 @@ -1597,14 +1597,15 @@ public class PackWriter implements AutoCloseable { } } - TemporaryBuffer.Heap delta = delta(otp); - out.writeHeader(otp, delta.length()); + try (TemporaryBuffer.Heap delta = delta(otp)) { + out.writeHeader(otp, delta.length()); - Deflater deflater = deflater(); - deflater.reset(); - DeflaterOutputStream dst = new DeflaterOutputStream(out, deflater); - delta.writeTo(dst, null); - dst.finish(); + Deflater deflater = deflater(); + deflater.reset(); + DeflaterOutputStream dst = new DeflaterOutputStream(out, deflater); + delta.writeTo(dst, null); + dst.finish(); + } typeStats.cntDeltas++; typeStats.deltaBytes += out.length() - otp.getOffset(); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriterBitmapWalker.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriterBitmapWalker.java index d9ac9ef16b..2ec4d568c7 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriterBitmapWalker.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriterBitmapWalker.java @@ -49,11 +49,11 @@ import java.util.Set; import org.eclipse.jgit.errors.IncorrectObjectTypeException; import org.eclipse.jgit.errors.MissingObjectException; import org.eclipse.jgit.lib.BitmapIndex; +import org.eclipse.jgit.lib.BitmapIndex.Bitmap; +import org.eclipse.jgit.lib.BitmapIndex.BitmapBuilder; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.NullProgressMonitor; import org.eclipse.jgit.lib.ObjectId; -import org.eclipse.jgit.lib.BitmapIndex.Bitmap; -import org.eclipse.jgit.lib.BitmapIndex.BitmapBuilder; import org.eclipse.jgit.lib.ProgressMonitor; import org.eclipse.jgit.revwalk.ObjectWalk; import org.eclipse.jgit.revwalk.RevCommit; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftree/Scanner.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftree/Scanner.java index d383abf316..2ef0f20d8d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftree/Scanner.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftree/Scanner.java @@ -43,7 +43,6 @@ package org.eclipse.jgit.internal.storage.reftree; -import static org.eclipse.jgit.lib.RefDatabase.MAX_SYMBOLIC_REF_DEPTH; import static org.eclipse.jgit.lib.Constants.OBJ_BLOB; import static org.eclipse.jgit.lib.Constants.R_REFS; import static org.eclipse.jgit.lib.Constants.encode; @@ -52,6 +51,7 @@ import static org.eclipse.jgit.lib.FileMode.TYPE_SYMLINK; import static org.eclipse.jgit.lib.FileMode.TYPE_TREE; import static org.eclipse.jgit.lib.Ref.Storage.NEW; import static org.eclipse.jgit.lib.Ref.Storage.PACKED; +import static org.eclipse.jgit.lib.RefDatabase.MAX_SYMBOLIC_REF_DEPTH; import java.io.IOException; 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 8550ec3a3f..653c9f66b6 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchRefUpdate.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchRefUpdate.java @@ -49,18 +49,21 @@ import static org.eclipse.jgit.transport.ReceiveCommand.Result.REJECTED_OTHER_RE import java.io.IOException; import java.text.MessageFormat; +import java.time.Duration; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.List; +import java.util.concurrent.TimeoutException; import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.lib.RefUpdate.Result; import org.eclipse.jgit.revwalk.RevWalk; import org.eclipse.jgit.transport.PushCertificate; import org.eclipse.jgit.transport.ReceiveCommand; +import org.eclipse.jgit.util.time.ProposedTimestamp; /** * Batch of reference updates to be applied to a repository. @@ -69,6 +72,17 @@ import org.eclipse.jgit.transport.ReceiveCommand; * server is making changes to more than one reference at a time. */ public class BatchRefUpdate { + /** + * Maximum delay the calling thread will tolerate while waiting for a + * {@code MonotonicClock} to resolve associated {@link ProposedTimestamp}s. + * <p> + * A default of 5 seconds was chosen by guessing. A common assumption is + * clock skew between machines on the same LAN using an NTP server also on + * the same LAN should be under 5 seconds. 5 seconds is also not that long + * for a large `git push` operation to complete. + */ + private static final Duration MAX_WAIT = Duration.ofSeconds(5); + private final RefDatabase refdb; /** Commands to apply during this batch. */ @@ -95,6 +109,9 @@ public class BatchRefUpdate { /** Push options associated with this update. */ private List<String> pushOptions; + /** Associated timestamps that should be blocked on before update. */ + private List<ProposedTimestamp> timestamps; + /** * Initialize a new batch update. * @@ -314,6 +331,32 @@ public class BatchRefUpdate { } /** + * @return list of timestamps the batch must wait for. + * @since 4.6 + */ + public List<ProposedTimestamp> getProposedTimestamps() { + if (timestamps != null) { + return Collections.unmodifiableList(timestamps); + } + return Collections.emptyList(); + } + + /** + * Request the batch to wait for the affected timestamps to resolve. + * + * @param ts + * @return {@code this}. + * @since 4.6 + */ + public BatchRefUpdate addProposedTimestamp(ProposedTimestamp ts) { + if (timestamps == null) { + timestamps = new ArrayList<>(4); + } + timestamps.add(ts); + return this; + } + + /** * Execute this batch update. * <p> * The default implementation of this method performs a sequential reference @@ -348,6 +391,9 @@ public class BatchRefUpdate { } return; } + if (!blockUntilTimestamps(MAX_WAIT)) { + return; + } if (options != null) { pushOptions = options; @@ -433,6 +479,33 @@ public class BatchRefUpdate { } /** + * Wait for timestamps to be in the past, aborting commands on timeout. + * + * @param maxWait + * maximum amount of time to wait for timestamps to resolve. + * @return true if timestamps were successfully waited for; false if + * commands were aborted. + * @since 4.6 + */ + protected boolean blockUntilTimestamps(Duration maxWait) { + if (timestamps == null) { + return true; + } + try { + ProposedTimestamp.blockUntil(timestamps, maxWait); + return true; + } catch (TimeoutException | InterruptedException e) { + String msg = JGitText.get().timeIsUncertain; + for (ReceiveCommand c : commands) { + if (c.getResult() == NOT_ATTEMPTED) { + c.setResult(REJECTED_OTHER_REASON, msg); + } + } + return false; + } + } + + /** * Execute this batch update without option strings. * * @param walk 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 9e3e0b78fd..cde41c2124 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java @@ -65,6 +65,12 @@ public class ConfigConstants { /** The "dfs" section */ public static final String CONFIG_DFS_SECTION = "dfs"; + /** + * The "receive" section + * @since 4.6 + */ + public static final String CONFIG_RECEIVE_SECTION = "receive"; + /** The "user" section */ public static final String CONFIG_USER_SECTION = "user"; @@ -101,6 +107,12 @@ public class ConfigConstants { */ public static final String CONFIG_PULL_SECTION = "pull"; + /** + * The "filter" section + * @since 4.6 + */ + public static final String CONFIG_FILTER_SECTION = "filter"; + /** The "algorithm" key */ public static final String CONFIG_KEY_ALGORITHM = "algorithm"; @@ -108,6 +120,24 @@ public class ConfigConstants { public static final String CONFIG_KEY_AUTOCRLF = "autocrlf"; /** + * The "auto" key + * @since 4.6 + */ + public static final String CONFIG_KEY_AUTO = "auto"; + + /** + * The "autogc" key + * @since 4.6 + */ + public static final String CONFIG_KEY_AUTOGC = "autogc"; + + /** + * The "autopacklimit" key + * @since 4.6 + */ + public static final String CONFIG_KEY_AUTOPACKLIMIT = "autopacklimit"; + + /** * The "eol" key * * @since 4.3 @@ -145,6 +175,13 @@ public class ConfigConstants { /** The "blockSize" key */ public static final String CONFIG_KEY_BLOCK_SIZE = "blockSize"; + /** + * The "concurrencyLevel" key + * + * @since 4.6 + */ + public static final String CONFIG_KEY_CONCURRENCY_LEVEL = "concurrencyLevel"; + /** The "deltaBaseCacheLimit" key */ public static final String CONFIG_KEY_DELTA_BASE_CACHE_LIMIT = "deltaBaseCacheLimit"; @@ -330,4 +367,11 @@ public class ConfigConstants { * @since 4.0 */ public static final String CONFIG_KEY_STREAM_RATIO = "streamRatio"; + + /** + * Flag in the filter section whether to use JGit's implementations of + * filters and hooks + * @since 4.6 + */ + public static final String CONFIG_KEY_USEJGITBUILTIN = "useJGitBuiltin"; } 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 d30edaf41b..ff80672f80 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Constants.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Constants.java @@ -391,6 +391,13 @@ public final class Constants { */ public static final String ATTR_FILTER_TYPE_SMUDGE = "smudge"; + /** + * Builtin filter commands start with this prefix + * + * @since 4.6 + */ + public static final String BUILTIN_FILTER_PREFIX = "jgit://builtin/"; + /** Name of the ignore file */ public static final String DOT_GIT_IGNORE = ".gitignore"; 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 9e474f86a8..af6a4fb919 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/IndexDiff.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/IndexDiff.java @@ -65,7 +65,6 @@ import org.eclipse.jgit.errors.IncorrectObjectTypeException; import org.eclipse.jgit.errors.MissingObjectException; import org.eclipse.jgit.errors.StopWalkException; import org.eclipse.jgit.internal.JGitText; -import org.eclipse.jgit.revwalk.RevTree; import org.eclipse.jgit.revwalk.RevWalk; import org.eclipse.jgit.submodule.SubmoduleWalk; import org.eclipse.jgit.submodule.SubmoduleWalk.IgnoreSubmoduleMode; @@ -73,8 +72,8 @@ import org.eclipse.jgit.treewalk.AbstractTreeIterator; import org.eclipse.jgit.treewalk.EmptyTreeIterator; import org.eclipse.jgit.treewalk.FileTreeIterator; import org.eclipse.jgit.treewalk.TreeWalk; -import org.eclipse.jgit.treewalk.WorkingTreeIterator; import org.eclipse.jgit.treewalk.TreeWalk.OperationType; +import org.eclipse.jgit.treewalk.WorkingTreeIterator; import org.eclipse.jgit.treewalk.filter.AndTreeFilter; import org.eclipse.jgit.treewalk.filter.IndexDiffFilter; import org.eclipse.jgit.treewalk.filter.SkipWorkTreeFilter; @@ -248,7 +247,7 @@ public class IndexDiff { private final Repository repository; - private final RevTree tree; + private final AnyObjectId tree; private TreeFilter filter = null; @@ -311,10 +310,13 @@ public class IndexDiff { public IndexDiff(Repository repository, ObjectId objectId, WorkingTreeIterator workingTreeIterator) throws IOException { this.repository = repository; - if (objectId != null) - tree = new RevWalk(repository).parseTree(objectId); - else + if (objectId != null) { + try (RevWalk rw = new RevWalk(repository)) { + tree = rw.parseTree(objectId); + } + } else { tree = null; + } this.initialWorkingTreeIterator = workingTreeIterator; } 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 0b5efd77d4..feecbd81c0 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectChecker.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectChecker.java @@ -709,11 +709,12 @@ public class ObjectChecker { return ptr; } - @SuppressWarnings("resource") @Nullable private ObjectId idFor(int objType, byte[] raw) { if (skipList != null) { - return new ObjectInserter.Formatter().idFor(objType, raw); + try (ObjectInserter.Formatter fmt = new ObjectInserter.Formatter()) { + return fmt.idFor(objType, raw); + } } return null; } 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 4edb38c5df..2a2d67d25a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectId.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectId.java @@ -44,15 +44,15 @@ package org.eclipse.jgit.lib; -import org.eclipse.jgit.errors.InvalidObjectIdException; -import org.eclipse.jgit.util.NB; -import org.eclipse.jgit.util.RawParseUtils; - import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; +import org.eclipse.jgit.errors.InvalidObjectIdException; +import org.eclipse.jgit.util.NB; +import org.eclipse.jgit.util.RawParseUtils; + /** * A SHA-1 abstraction. */ diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectIdOwnerMap.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectIdOwnerMap.java index 442261cbd5..95cb976372 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectIdOwnerMap.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectIdOwnerMap.java @@ -143,6 +143,7 @@ public class ObjectIdOwnerMap<V extends ObjectIdOwnerMap.Entry> * 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; } @@ -219,20 +220,20 @@ public class ObjectIdOwnerMap<V extends ObjectIdOwnerMap.Entry> return size == 0; } + @Override public Iterator<V> iterator() { return new Iterator<V>() { private int found; - private int dirIdx; - private int tblIdx; - private V next; + @Override public boolean hasNext() { return found < size; } + @Override public V next() { if (next != null) return found(next); @@ -261,6 +262,7 @@ public class ObjectIdOwnerMap<V extends ObjectIdOwnerMap.Entry> return v; } + @Override public void remove() { throw new UnsupportedOperationException(); } @@ -341,7 +343,7 @@ public class ObjectIdOwnerMap<V extends ObjectIdOwnerMap.Entry> /** Type of entry stored in the {@link ObjectIdOwnerMap}. */ public static abstract class Entry extends ObjectId { - Entry next; + transient Entry next; /** * Initialize this entry with a specific ObjectId. 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 b23145d798..372da98939 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectReader.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectReader.java @@ -66,6 +66,13 @@ public abstract class ObjectReader implements AutoCloseable { public static final int OBJ_ANY = -1; /** + * The threshold at which a file will be streamed rather than loaded + * entirely into memory. + * @since 4.6 + */ + protected int streamFileThreshold; + + /** * Construct a new reader from the same data. * <p> * Applications can use this method to build a new reader from the same data @@ -445,6 +452,29 @@ public abstract class ObjectReader implements AutoCloseable { public abstract void close(); /** + * Sets the threshold at which a file will be streamed rather than loaded + * entirely into memory + * + * @param threshold + * the new threshold + * @since 4.6 + */ + public void setStreamFileThreshold(int threshold) { + streamFileThreshold = threshold; + } + + /** + * Returns the threshold at which a file will be streamed rather than loaded + * entirely into memory + * + * @return the threshold in bytes + * @since 4.6 + */ + public int getStreamFileThreshold() { + return streamFileThreshold; + } + + /** * Wraps a delegate ObjectReader. * * @since 4.4 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 e08a98529d..627ccaa206 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/PersonIdent.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/PersonIdent.java @@ -53,6 +53,7 @@ import java.util.TimeZone; import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.util.SystemReader; +import org.eclipse.jgit.util.time.ProposedTimestamp; /** * A combination of a person identity and time in Git. @@ -189,6 +190,19 @@ public class PersonIdent implements Serializable { } /** + * Construct a new {@link PersonIdent} with current time. + * + * @param aName + * @param aEmailAddress + * @param when + * @since 4.6 + */ + public PersonIdent(String aName, String aEmailAddress, + ProposedTimestamp when) { + this(aName, aEmailAddress, when.millis()); + } + + /** * Copy a PersonIdent, but alter the clone's time stamp * * @param pi 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 4ebe5fedf3..75a3592213 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RebaseTodoFile.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RebaseTodoFile.java @@ -43,6 +43,7 @@ package org.eclipse.jgit.lib; +import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; @@ -53,7 +54,6 @@ import java.util.List; import org.eclipse.jgit.lib.RebaseTodoLine.Action; import org.eclipse.jgit.util.IO; import org.eclipse.jgit.util.RawParseUtils; -import org.eclipse.jgit.util.io.SafeBufferedOutputStream; /** * Offers methods to read and write files formatted like the git-rebase-todo @@ -216,9 +216,8 @@ public class RebaseTodoFile { */ public void writeRebaseTodoFile(String path, List<RebaseTodoLine> steps, boolean append) throws IOException { - OutputStream fw = new SafeBufferedOutputStream(new FileOutputStream( - new File(repo.getDirectory(), path), append)); - try { + try (OutputStream fw = new BufferedOutputStream(new FileOutputStream( + new File(repo.getDirectory(), path), append))) { StringBuilder sb = new StringBuilder(); for (RebaseTodoLine step : steps) { sb.setLength(0); @@ -234,8 +233,6 @@ public class RebaseTodoFile { sb.append('\n'); fw.write(Constants.encode(sb.toString())); } - } finally { - fw.close(); } } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ReflogEntry.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ReflogEntry.java index e2102e54f0..0504646ee7 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ReflogEntry.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ReflogEntry.java @@ -42,9 +42,6 @@ */ package org.eclipse.jgit.lib; -import org.eclipse.jgit.lib.ObjectId; -import org.eclipse.jgit.lib.PersonIdent; - /** * Parsed reflog entry * 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 aba5242b14..c5b2ef8e5b 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java @@ -52,6 +52,7 @@ import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; +import java.io.OutputStream; import java.net.URISyntaxException; import java.text.MessageFormat; import java.util.Collection; @@ -80,6 +81,7 @@ import org.eclipse.jgit.events.IndexChangedListener; import org.eclipse.jgit.events.ListenerList; import org.eclipse.jgit.events.RepositoryEvent; import org.eclipse.jgit.internal.JGitText; +import org.eclipse.jgit.internal.storage.file.GC; import org.eclipse.jgit.revwalk.RevBlob; import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevObject; @@ -93,7 +95,6 @@ import org.eclipse.jgit.util.FileUtils; import org.eclipse.jgit.util.IO; import org.eclipse.jgit.util.RawParseUtils; import org.eclipse.jgit.util.SystemReader; -import org.eclipse.jgit.util.io.SafeBufferedOutputStream; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -106,8 +107,7 @@ import org.slf4j.LoggerFactory; * This class is thread-safe. */ public abstract class Repository implements AutoCloseable { - private static Logger LOG = LoggerFactory.getLogger(Repository.class); - + private static final Logger LOG = LoggerFactory.getLogger(Repository.class); private static final ListenerList globalListeners = new ListenerList(); /** @return the global listener list observing all events in this JVM. */ @@ -245,7 +245,6 @@ public abstract class Repository implements AutoCloseable { @NonNull public abstract AttributesNodeProvider createAttributesNodeProvider(); - /** * @return the used file system abstraction, or or {@code null} if * repository isn't local. @@ -653,7 +652,10 @@ public abstract class Repository implements AutoCloseable { // detached name = Constants.HEAD; if (!Repository.isValidRefName("x/" + name)) //$NON-NLS-1$ - throw new RevisionSyntaxException(revstr); + throw new RevisionSyntaxException(MessageFormat + .format(JGitText.get().invalidRefName, + name), + revstr); Ref ref = getRef(name); name = null; if (ref == null) @@ -703,7 +705,10 @@ public abstract class Repository implements AutoCloseable { if (name.equals("")) //$NON-NLS-1$ name = Constants.HEAD; if (!Repository.isValidRefName("x/" + name)) //$NON-NLS-1$ - throw new RevisionSyntaxException(revstr); + throw new RevisionSyntaxException(MessageFormat + .format(JGitText.get().invalidRefName, + name), + revstr); Ref ref = getRef(name); name = null; if (ref == null) @@ -752,7 +757,9 @@ public abstract class Repository implements AutoCloseable { return null; name = revstr.substring(done); if (!Repository.isValidRefName("x/" + name)) //$NON-NLS-1$ - throw new RevisionSyntaxException(revstr); + throw new RevisionSyntaxException( + MessageFormat.format(JGitText.get().invalidRefName, name), + revstr); if (getRef(name) != null) return name; return resolveSimple(name); @@ -869,6 +876,7 @@ public abstract class Repository implements AutoCloseable { } /** Decrement the use count, and maybe close resources. */ + @Override public void close() { int newCount = useCnt.decrementAndGet(); if (newCount == 0) { @@ -902,8 +910,9 @@ public abstract class Repository implements AutoCloseable { getRefDatabase().close(); } - @NonNull @SuppressWarnings("nls") + @Override + @NonNull public String toString() { String desc; File directory = getDirectory(); @@ -1175,7 +1184,7 @@ public abstract class Repository implements AutoCloseable { // we want DirCache to inform us so that we can inform registered // listeners about index changes IndexChangedListener l = new IndexChangedListener() { - + @Override public void onIndexChanged(IndexChangedEvent event) { notifyIndexChanged(); } @@ -1183,15 +1192,6 @@ public abstract class Repository implements AutoCloseable { return DirCache.lock(this, l); } - static byte[] gitInternalSlash(byte[] bytes) { - if (File.separatorChar == '/') - return bytes; - for (int i=0; i<bytes.length; ++i) - if (bytes[i] == File.separatorChar) - bytes[i] = '/'; - return bytes; - } - /** * @return an important state */ @@ -1445,6 +1445,33 @@ public abstract class Repository implements AutoCloseable { } /** + * Read the {@code GIT_DIR/description} file for gitweb. + * + * @return description text; null if no description has been configured. + * @throws IOException + * description cannot be accessed. + * @since 4.6 + */ + @Nullable + public String getGitwebDescription() throws IOException { + return null; + } + + /** + * Set the {@code GIT_DIR/description} file for gitweb. + * + * @param description + * new description; null to clear the description. + * @throws IOException + * description cannot be persisted. + * @since 4.6 + */ + public void setGitwebDescription(@Nullable String description) + throws IOException { + throw new IOException(JGitText.get().unsupportedRepositoryDescription); + } + + /** * @param refName * @return a {@link ReflogReader} for the supplied refname, or {@code null} * if the named ref does not exist. @@ -1781,15 +1808,12 @@ public abstract class Repository implements AutoCloseable { throws FileNotFoundException, IOException { File headsFile = new File(getDirectory(), filename); if (heads != null) { - BufferedOutputStream bos = new SafeBufferedOutputStream( - new FileOutputStream(headsFile)); - try { + try (OutputStream bos = new BufferedOutputStream( + new FileOutputStream(headsFile))) { for (ObjectId id : heads) { id.copyTo(bos); bos.write('\n'); } - } finally { - bos.close(); } } else { FileUtils.delete(headsFile, FileUtils.SKIP_MISSING); @@ -1845,4 +1869,22 @@ public abstract class Repository implements AutoCloseable { return getConfig() .getSubsections(ConfigConstants.CONFIG_REMOTE_SECTION); } + + /** + * Check whether any housekeeping is required; if yes, run garbage + * collection; if not, exit without performing any work. Some JGit commands + * run autoGC after performing operations that could create many loose + * objects. + * <p/> + * Currently this option is supported for repositories of type + * {@code FileRepository} only. See {@link GC#setAuto(boolean)} for + * configuration details. + * + * @param monitor + * to report progress + * @since 4.6 + */ + public void autoGC(ProgressMonitor monitor) { + // default does nothing + } } 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 7a8d246df2..2f1a9e1cda 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RepositoryCache.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RepositoryCache.java @@ -45,12 +45,8 @@ package org.eclipse.jgit.lib; import java.io.File; import java.io.IOException; -import java.lang.ref.Reference; -import java.lang.ref.SoftReference; import java.util.ArrayList; import java.util.Collection; -import java.util.Iterator; -import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledThreadPoolExecutor; @@ -150,7 +146,7 @@ public class RepositoryCache { public static void close(@NonNull final Repository db) { if (db.getDirectory() != null) { FileKey key = FileKey.exact(db.getDirectory(), db.getFS()); - cache.unregisterAndCloseRepository(key, db); + cache.unregisterAndCloseRepository(key); } } @@ -202,8 +198,7 @@ public class RepositoryCache { return false; } FileKey key = new FileKey(gitDir, repo.getFS()); - Reference<Repository> repoRef = cache.cacheMap.get(key); - return repoRef != null && repoRef.get() == repo; + return cache.cacheMap.get(key) == repo; } /** Unregister all repositories from the cache. */ @@ -219,7 +214,7 @@ public class RepositoryCache { cache.configureEviction(repositoryCacheConfig); } - private final ConcurrentHashMap<Key, Reference<Repository>> cacheMap; + private final ConcurrentHashMap<Key, Repository> cacheMap; private final Lock[] openLocks; @@ -228,7 +223,7 @@ public class RepositoryCache { private volatile long expireAfter; private RepositoryCache() { - cacheMap = new ConcurrentHashMap<Key, Reference<Repository>>(); + cacheMap = new ConcurrentHashMap<>(); openLocks = new Lock[4]; for (int i = 0; i < openLocks.length; i++) { openLocks[i] = new Lock(); @@ -261,19 +256,15 @@ public class RepositoryCache { } } - @SuppressWarnings("resource") private Repository openRepository(final Key location, final boolean mustExist) throws IOException { - Reference<Repository> ref = cacheMap.get(location); - Repository db = ref != null ? ref.get() : null; + Repository db = cacheMap.get(location); if (db == null) { synchronized (lockFor(location)) { - ref = cacheMap.get(location); - db = ref != null ? ref.get() : null; + db = cacheMap.get(location); if (db == null) { db = location.open(mustExist); - ref = new SoftReference<Repository>(db); - cacheMap.put(location, ref); + cacheMap.put(location, db); } else { db.incrementOpen(); } @@ -285,16 +276,13 @@ public class RepositoryCache { } private void registerRepository(final Key location, final Repository db) { - SoftReference<Repository> newRef = new SoftReference<Repository>(db); - Reference<Repository> oldRef = cacheMap.put(location, newRef); - Repository oldDb = oldRef != null ? oldRef.get() : null; + Repository oldDb = cacheMap.put(location, db); if (oldDb != null) oldDb.close(); } private Repository unregisterRepository(final Key location) { - Reference<Repository> oldRef = cacheMap.remove(location); - return oldRef != null ? oldRef.get() : null; + return cacheMap.remove(location); } private boolean isExpired(Repository db) { @@ -302,8 +290,7 @@ public class RepositoryCache { && (System.currentTimeMillis() - db.closedAt.get() > expireAfter); } - private void unregisterAndCloseRepository(final Key location, - Repository db) { + private void unregisterAndCloseRepository(final Key location) { synchronized (lockFor(location)) { Repository oldDb = unregisterRepository(location); if (oldDb != null) { @@ -317,8 +304,7 @@ public class RepositoryCache { } private void clearAllExpired() { - for (Reference<Repository> ref : cacheMap.values()) { - Repository db = ref.get(); + for (Repository db : cacheMap.values()) { if (isExpired(db)) { RepositoryCache.close(db); } @@ -326,9 +312,8 @@ public class RepositoryCache { } private void clearAll() { - for (Iterator<Map.Entry<Key, Reference<Repository>>> i = cacheMap - .entrySet().iterator(); i.hasNext();) { - unregisterAndCloseRepository(i.next().getKey(), null); + for (Key k : cacheMap.keySet()) { + unregisterAndCloseRepository(k); } } @@ -442,6 +427,7 @@ public class RepositoryCache { return path; } + @Override public Repository open(final boolean mustExist) throws IOException { if (mustExist && !isGitRepository(path, fs)) throw new RepositoryNotFoundException(path); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RepositoryCacheConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RepositoryCacheConfig.java index 428dea3e67..28cdaae443 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RepositoryCacheConfig.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RepositoryCacheConfig.java @@ -53,8 +53,8 @@ public class RepositoryCacheConfig { /** * Set cleanupDelayMillis to this value in order to switch off time-based - * cache eviction. The JVM can still expire cache entries when heap memory - * runs low. + * cache eviction. Expired cache entries will only be evicted when + * RepositoryCache.clearExpired or RepositoryCache.clear are called. */ public static final long NO_CLEANUP = 0; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/TreeFormatter.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/TreeFormatter.java index 065b8f46b6..777ce94aa0 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/TreeFormatter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/TreeFormatter.java @@ -53,6 +53,7 @@ import static org.eclipse.jgit.lib.FileMode.TREE; import java.io.IOException; import org.eclipse.jgit.errors.CorruptObjectException; +import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.revwalk.RevBlob; import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevTree; @@ -193,6 +194,34 @@ public class TreeFormatter { */ public void append(byte[] nameBuf, int namePos, int nameLen, FileMode mode, AnyObjectId id) { + append(nameBuf, namePos, nameLen, mode, id, false); + } + + /** + * Append any entry to the tree. + * + * @param nameBuf + * buffer holding the name of the entry. The name should be UTF-8 + * encoded, but file name encoding is not a well defined concept + * in Git. + * @param namePos + * first position within {@code nameBuf} of the name data. + * @param nameLen + * number of bytes from {@code nameBuf} to use as the name. + * @param mode + * mode describing the treatment of {@code id}. + * @param id + * the ObjectId to store in this entry. + * @param allowEmptyName + * allow an empty filename (creating a corrupt tree) + * @since 4.6 + */ + public void append(byte[] nameBuf, int namePos, int nameLen, FileMode mode, + AnyObjectId id, boolean allowEmptyName) { + if (nameLen == 0 && !allowEmptyName) { + throw new IllegalArgumentException( + JGitText.get().invalidTreeZeroLengthName); + } if (fmtBuf(nameBuf, namePos, nameLen, mode)) { id.copyRawTo(buf, ptr); ptr += OBJECT_ID_LENGTH; 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 9125ddfd68..83b143b90d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeConfig.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/MergeConfig.java @@ -46,8 +46,8 @@ import java.io.IOException; import org.eclipse.jgit.api.MergeCommand.FastForwardMode; import org.eclipse.jgit.lib.Config; -import org.eclipse.jgit.lib.ConfigConstants; import org.eclipse.jgit.lib.Config.SectionParser; +import org.eclipse.jgit.lib.ConfigConstants; import org.eclipse.jgit.lib.Repository; /** 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 383c1f8fef..40ea77e8ec 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/patch/Patch.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/patch/Patch.java @@ -44,9 +44,9 @@ package org.eclipse.jgit.patch; import static org.eclipse.jgit.lib.Constants.encodeASCII; -import static org.eclipse.jgit.patch.FileHeader.isHunkHdr; import static org.eclipse.jgit.patch.FileHeader.NEW_NAME; import static org.eclipse.jgit.patch.FileHeader.OLD_NAME; +import static org.eclipse.jgit.patch.FileHeader.isHunkHdr; import static org.eclipse.jgit.util.RawParseUtils.match; import static org.eclipse.jgit.util.RawParseUtils.nextLF; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revplot/PlotCommit.java b/org.eclipse.jgit/src/org/eclipse/jgit/revplot/PlotCommit.java index 2e8aab885a..98bcd1accf 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revplot/PlotCommit.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revplot/PlotCommit.java @@ -44,8 +44,8 @@ package org.eclipse.jgit.revplot; import org.eclipse.jgit.lib.AnyObjectId; -import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.lib.Ref; +import org.eclipse.jgit.revwalk.RevCommit; /** * A commit reference to a commit in the DAG. 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 f1d7dc8361..3609d46e30 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/MergeBaseGenerator.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/MergeBaseGenerator.java @@ -45,6 +45,7 @@ package org.eclipse.jgit.revwalk; import java.io.IOException; import java.text.MessageFormat; +import java.util.LinkedList; import org.eclipse.jgit.errors.IncorrectObjectTypeException; import org.eclipse.jgit.errors.MissingObjectException; @@ -85,12 +86,15 @@ class MergeBaseGenerator extends Generator { private int recarryMask; + private int mergeBaseAncestor = -1; + private LinkedList<RevCommit> ret = new LinkedList<RevCommit>(); + MergeBaseGenerator(final RevWalk w) { walker = w; pending = new DateRevQueue(); } - void init(final AbstractRevQueue p) { + void init(final AbstractRevQueue p) throws IOException { try { for (;;) { final RevCommit c = p.next(); @@ -98,17 +102,25 @@ class MergeBaseGenerator extends Generator { break; add(c); } - } finally { - // Always free the flags immediately. This ensures the flags - // will be available for reuse when the walk resets. - // - walker.freeFlag(branchMask); - // Setup the condition used by carryOntoOne to detect a late // merge base and produce it on the next round. // recarryTest = branchMask | POPPED; recarryMask = branchMask | POPPED | MERGE_BASE; + mergeBaseAncestor = walker.allocFlag(); + + for (;;) { + RevCommit c = _next(); + if (c == null) { + break; + } + ret.add(c); + } + } finally { + // Always free the flags immediately. This ensures the flags + // will be available for reuse when the walk resets. + // + walker.freeFlag(branchMask | mergeBaseAncestor); } } @@ -131,8 +143,7 @@ class MergeBaseGenerator extends Generator { return 0; } - @Override - RevCommit next() throws MissingObjectException, + private RevCommit _next() throws MissingObjectException, IncorrectObjectTypeException, IOException { for (;;) { final RevCommit c = pending.next(); @@ -156,7 +167,7 @@ class MergeBaseGenerator extends Generator { // also flagged as being popped, so that they do not // generate to the caller. // - carry |= MERGE_BASE; + carry |= MERGE_BASE | mergeBaseAncestor; } carryOntoHistory(c, carry); @@ -179,6 +190,18 @@ class MergeBaseGenerator extends Generator { } } + @Override + RevCommit next() throws MissingObjectException, + IncorrectObjectTypeException, IOException { + while (!ret.isEmpty()) { + RevCommit commit = ret.remove(); + if ((commit.flags & mergeBaseAncestor) == 0) { + return commit; + } + } + return null; + } + private void carryOntoHistory(RevCommit c, final int carry) { for (;;) { final RevCommit[] pList = c.parents; 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 4b4822c763..38a0fa2aac 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 @@ -55,8 +55,8 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.text.MessageFormat; -import org.eclipse.jgit.errors.LockFailedException; import org.eclipse.jgit.errors.ConfigInvalidException; +import org.eclipse.jgit.errors.LockFailedException; import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.internal.storage.file.FileSnapshot; import org.eclipse.jgit.internal.storage.file.LockFile; 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 4069a64535..1aebaddacd 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/AmazonS3.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/AmazonS3.java @@ -529,21 +529,29 @@ public class AmazonS3 { Integer.valueOf(HttpSupport.response(c)), c.getResponseMessage())); final InputStream errorStream = c.getErrorStream(); - if (errorStream == null) + if (errorStream == null) { return err; + } - final ByteArrayOutputStream b = new ByteArrayOutputStream(); - byte[] buf = new byte[2048]; - for (;;) { - final int n = errorStream.read(buf); - if (n < 0) - break; - if (n > 0) - b.write(buf, 0, n); + try { + final ByteArrayOutputStream b = new ByteArrayOutputStream(); + byte[] buf = new byte[2048]; + for (;;) { + final int n = errorStream.read(buf); + if (n < 0) { + break; + } + if (n > 0) { + b.write(buf, 0, n); + } + } + buf = b.toByteArray(); + if (buf.length > 0) { + err.initCause(new IOException("\n" + new String(buf))); //$NON-NLS-1$ + } + } finally { + errorStream.close(); } - buf = b.toByteArray(); - if (buf.length > 0) - err.initCause(new IOException("\n" + new String(buf))); //$NON-NLS-1$ return err; } 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 754cf361a9..0dd907f97e 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackFetchConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackFetchConnection.java @@ -71,7 +71,6 @@ import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectInserter; import org.eclipse.jgit.lib.ProgressMonitor; import org.eclipse.jgit.lib.Ref; -import org.eclipse.jgit.transport.GitProtocolConstants.MultiAck; import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevCommitList; import org.eclipse.jgit.revwalk.RevFlag; @@ -80,6 +79,7 @@ import org.eclipse.jgit.revwalk.RevSort; import org.eclipse.jgit.revwalk.RevWalk; import org.eclipse.jgit.revwalk.filter.CommitTimeRevFilter; import org.eclipse.jgit.revwalk.filter.RevFilter; +import org.eclipse.jgit.transport.GitProtocolConstants.MultiAck; import org.eclipse.jgit.transport.PacketLineIn.AckNackResult; import org.eclipse.jgit.util.TemporaryBuffer; 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 0724eac701..4d0803a339 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseReceivePack.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseReceivePack.java @@ -69,6 +69,7 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.TimeUnit; +import org.eclipse.jgit.annotations.Nullable; import org.eclipse.jgit.errors.InvalidObjectIdException; import org.eclipse.jgit.errors.MissingObjectException; import org.eclipse.jgit.errors.PackProtocolException; @@ -268,6 +269,7 @@ public abstract class BaseReceivePack { private PushCertificateParser pushCertificateParser; private SignedPushConfig signedPushConfig; private PushCertificate pushCert; + private ReceivedPackStatistics stats; /** * Get the push certificate used to verify the pusher's identity. @@ -1115,6 +1117,18 @@ public abstract class BaseReceivePack { } /** + * Returns the statistics on the received pack if available. This should be + * called after {@link #receivePack} is called. + * + * @return ReceivedPackStatistics + * @since 4.6 + */ + @Nullable + public ReceivedPackStatistics getReceivedPackStatistics() { + return stats; + } + + /** * Receive a list of commands from the input. * * @throws IOException @@ -1307,6 +1321,7 @@ public abstract class BaseReceivePack { parser.setMaxObjectSizeLimit(maxObjectSizeLimit); packLock = parser.parse(receiving, resolving); packSize = Long.valueOf(parser.getPackSize()); + stats = parser.getReceivedPackStatistics(); ins.flush(); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/DaemonClient.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/DaemonClient.java index 22f343899d..23e3379f91 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/DaemonClient.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/DaemonClient.java @@ -44,6 +44,7 @@ package org.eclipse.jgit.transport; import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -52,7 +53,6 @@ import java.net.Socket; import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException; import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; -import org.eclipse.jgit.util.io.SafeBufferedOutputStream; /** Active network client of {@link Daemon}. */ public class DaemonClient { @@ -95,7 +95,7 @@ public class DaemonClient { void execute(final Socket sock) throws IOException, ServiceNotEnabledException, ServiceNotAuthorizedException { rawIn = new BufferedInputStream(sock.getInputStream()); - rawOut = new SafeBufferedOutputStream(sock.getOutputStream()); + rawOut = new BufferedOutputStream(sock.getOutputStream()); if (0 < daemon.getTimeout()) sock.setSoTimeout(daemon.getTimeout() * 1000); 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 4e7e12399c..ec6f24273d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/DaemonService.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/DaemonService.java @@ -47,8 +47,8 @@ package org.eclipse.jgit.transport; import java.io.IOException; import org.eclipse.jgit.lib.Config; -import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.Config.SectionParser; +import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException; import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; 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 622680a27f..319ae1edc7 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/HMACSHA1NonceGenerator.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/HMACSHA1NonceGenerator.java @@ -52,7 +52,6 @@ import javax.crypto.spec.SecretKeySpec; import org.eclipse.jgit.internal.storage.dfs.DfsRepository; import org.eclipse.jgit.lib.Repository; -import org.eclipse.jgit.transport.NonceGenerator; import org.eclipse.jgit.transport.PushCertificate.NonceStatus; /** diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/InsecureCipherFactory.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/InsecureCipherFactory.java new file mode 100644 index 0000000000..73384a1162 --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/InsecureCipherFactory.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2016, Google Inc. + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.eclipse.jgit.transport; + +import java.security.NoSuchAlgorithmException; + +import javax.crypto.Cipher; +import javax.crypto.NoSuchPaddingException; + +/** + * <b>DO NOT USE</b> Factory to create any cipher. + * <p> + * This is a hack for {@link WalkEncryption} to create any cipher configured by + * the end-user. Using this class allows JGit to violate ErrorProne's security + * recommendations (<a + * href="http://errorprone.info/bugpattern/InsecureCryptoUsage" + * >InsecureCryptoUsage</a>), which is not secure. + */ +class InsecureCipherFactory { + static Cipher create(String algo) + throws NoSuchAlgorithmException, NoSuchPaddingException { + return Cipher.getInstance(algo); + } +} 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 1dfe5d9797..fa27bfce5f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/JschSession.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/JschSession.java @@ -48,15 +48,14 @@ package org.eclipse.jgit.transport; +import java.io.BufferedOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.io.PipedInputStream; -import java.io.PipedOutputStream; import org.eclipse.jgit.errors.TransportException; import org.eclipse.jgit.internal.JGitText; -import org.eclipse.jgit.util.io.StreamCopyThread; +import org.eclipse.jgit.util.io.IsolatedOutputStream; import com.jcraft.jsch.Channel; import com.jcraft.jsch.ChannelExec; @@ -178,33 +177,12 @@ public class JschSession implements RemoteSession { // that we spawn a background thread to shuttle data through a pipe, // as we can issue an interrupted write out of that. Its slower, so // we only use this route if there is a timeout. - final OutputStream out = channel.getOutputStream(); + OutputStream out = channel.getOutputStream(); if (timeout <= 0) { outputStream = out; } else { - final PipedInputStream pipeIn = new PipedInputStream(); - final StreamCopyThread copier = new StreamCopyThread(pipeIn, - out); - final PipedOutputStream pipeOut = new PipedOutputStream(pipeIn) { - @Override - public void flush() throws IOException { - super.flush(); - copier.flush(); - } - - @Override - public void close() throws IOException { - super.close(); - try { - copier.join(timeout * 1000); - } catch (InterruptedException e) { - // Just wake early, the thread will terminate - // anyway. - } - } - }; - copier.start(); - outputStream = pipeOut; + IsolatedOutputStream i = new IsolatedOutputStream(out); + outputStream = new BufferedOutputStream(i, 16 * 1024); } errStream = channel.getErrStream(); 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 b96fe885e1..4bbe3f8813 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PackParser.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PackParser.java @@ -186,6 +186,9 @@ public abstract class PackParser { /** Git object size limit */ private long maxObjectSizeLimit; + private final ReceivedPackStatistics.Builder stats = + new ReceivedPackStatistics.Builder(); + /** * Initialize a pack parser. * @@ -455,8 +458,8 @@ public abstract class PackParser { } /** - * Get the size of the parsed pack. - * + * Get the size of the newly created pack. + * <p> * This will also include the pack index size if an index was created. This * method should only be called after pack parsing is finished. * @@ -469,6 +472,18 @@ public abstract class PackParser { } /** + * Returns the statistics of the parsed pack. + * <p> + * This should only be called after pack parsing is finished. + * + * @return {@link ReceivedPackStatistics} + * @since 4.6 + */ + public ReceivedPackStatistics getReceivedPackStatistics() { + return stats.build(); + } + + /** * Parse the pack stream. * * @param progress @@ -626,6 +641,7 @@ public abstract class PackParser { private void resolveDeltas(DeltaVisit visit, final int type, ObjectTypeAndSize info, ProgressMonitor progress) throws IOException { + stats.addDeltaObject(type); do { progress.update(1); info = openDatabase(visit.delta, info); @@ -919,6 +935,7 @@ public abstract class PackParser { // Cleanup all resources associated with our input parsing. private void endInput() { + stats.setNumBytesRead(streamPosition()); in = null; } @@ -947,12 +964,14 @@ public abstract class PackParser { case Constants.OBJ_TREE: case Constants.OBJ_BLOB: case Constants.OBJ_TAG: + stats.addWholeObject(typeCode); onBeginWholeObject(streamPosition, typeCode, sz); onObjectHeader(Source.INPUT, hdrBuf, 0, hdrPtr); whole(streamPosition, typeCode, sz); break; case Constants.OBJ_OFS_DELTA: { + stats.addOffsetDelta(); c = readFrom(Source.INPUT); hdrBuf[hdrPtr++] = (byte) c; long ofs = c & 127; @@ -975,6 +994,7 @@ public abstract class PackParser { } case Constants.OBJ_REF_DELTA: { + stats.addRefDelta(); c = fill(Source.INPUT, 20); final ObjectId base = ObjectId.fromRaw(buf, c); System.arraycopy(buf, c, hdrBuf, hdrPtr, 20); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushCertificateIdent.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushCertificateIdent.java index 871a6f752b..4c8acd2cc2 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushCertificateIdent.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PushCertificateIdent.java @@ -44,7 +44,6 @@ package org.eclipse.jgit.transport; import static java.nio.charset.StandardCharsets.UTF_8; - import static org.eclipse.jgit.util.RawParseUtils.lastIndexOfTrim; import java.text.SimpleDateFormat; 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 cc20d50a7f..393e25a2a8 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java @@ -56,7 +56,9 @@ import java.util.List; import org.eclipse.jgit.annotations.Nullable; import org.eclipse.jgit.errors.UnpackException; +import org.eclipse.jgit.lib.ConfigConstants; import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.lib.NullProgressMonitor; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.transport.ReceiveCommand.Result; import org.eclipse.jgit.transport.RefAdvertiser.PacketLineOutRefAdvertiser; @@ -307,9 +309,19 @@ public class ReceivePack extends BaseReceivePack { throw new UnpackException(unpackError); } postReceive.onPostReceive(this, filterCommands(Result.OK)); + autoGc(); } } + private void autoGc() { + Repository repo = getRepository(); + if (!repo.getConfig().getBoolean(ConfigConstants.CONFIG_RECEIVE_SECTION, + ConfigConstants.CONFIG_KEY_AUTOGC, true)) { + return; + } + repo.autoGC(NullProgressMonitor.INSTANCE); + } + @Override protected String getLockMessageProcessName() { return "jgit receive-pack"; //$NON-NLS-1$ diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivedPackStatistics.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivedPackStatistics.java new file mode 100644 index 0000000000..052d5506f8 --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivedPackStatistics.java @@ -0,0 +1,231 @@ +/* + * Copyright (C) 2016, Google Inc. + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.eclipse.jgit.transport; + +import org.eclipse.jgit.lib.Constants; + +/** + * Statistics about {@link PackParser}. + * + * @since 4.6 + */ +public class ReceivedPackStatistics { + private long numBytesRead; + + private long numWholeCommit; + private long numWholeTree; + private long numWholeBlob; + private long numWholeTag; + private long numOfsDelta; + private long numRefDelta; + + private long numDeltaCommit; + private long numDeltaTree; + private long numDeltaBlob; + private long numDeltaTag; + + /** @return number of bytes read from the input stream */ + public long getNumBytesRead() { + return numBytesRead; + } + + /** @return number of whole commit objects in the pack */ + public long getNumWholeCommit() { + return numWholeCommit; + } + + /** @return number of whole tree objects in the pack */ + public long getNumWholeTree() { + return numWholeTree; + } + + /** @return number of whole blob objects in the pack */ + public long getNumWholeBlob() { + return numWholeBlob; + } + + /** @return number of whole tag objects in the pack */ + public long getNumWholeTag() { + return numWholeTag; + } + + /** @return number of offset delta objects in the pack */ + public long getNumOfsDelta() { + return numOfsDelta; + } + + /** @return number of ref delta objects in the pack */ + public long getNumRefDelta() { + return numRefDelta; + } + + /** @return number of delta commit objects in the pack */ + public long getNumDeltaCommit() { + return numDeltaCommit; + } + + /** @return number of delta tree objects in the pack */ + public long getNumDeltaTree() { + return numDeltaTree; + } + + /** @return number of delta blob objects in the pack */ + public long getNumDeltaBlob() { + return numDeltaBlob; + } + + /** @return number of delta tag objects in the pack */ + public long getNumDeltaTag() { + return numDeltaTag; + } + + /** A builder for {@link ReceivedPackStatistics}. */ + public static class Builder { + private long numBytesRead; + + private long numWholeCommit; + private long numWholeTree; + private long numWholeBlob; + private long numWholeTag; + private long numOfsDelta; + private long numRefDelta; + + private long numDeltaCommit; + private long numDeltaTree; + private long numDeltaBlob; + private long numDeltaTag; + + /** + * @param numBytesRead number of bytes read from the input stream + * @return this + */ + public Builder setNumBytesRead(long numBytesRead) { + this.numBytesRead = numBytesRead; + return this; + } + + /** + * Increment a whole object count. + * + * @param type OBJ_COMMIT, OBJ_TREE, OBJ_BLOB, or OBJ_TAG + * @return this + */ + public Builder addWholeObject(int type) { + switch (type) { + case Constants.OBJ_COMMIT: + numWholeCommit++; + break; + case Constants.OBJ_TREE: + numWholeTree++; + break; + case Constants.OBJ_BLOB: + numWholeBlob++; + break; + case Constants.OBJ_TAG: + numWholeTag++; + break; + default: + throw new IllegalArgumentException( + type + " cannot be a whole object"); //$NON-NLS-1$ + } + return this; + } + + /** @return this */ + public Builder addOffsetDelta() { + numOfsDelta++; + return this; + } + + /** @return this */ + public Builder addRefDelta() { + numRefDelta++; + return this; + } + + /** + * Increment a delta object count. + * + * @param type OBJ_COMMIT, OBJ_TREE, OBJ_BLOB, or OBJ_TAG + * @return this + */ + public Builder addDeltaObject(int type) { + switch (type) { + case Constants.OBJ_COMMIT: + numDeltaCommit++; + break; + case Constants.OBJ_TREE: + numDeltaTree++; + break; + case Constants.OBJ_BLOB: + numDeltaBlob++; + break; + case Constants.OBJ_TAG: + numDeltaTag++; + break; + default: + throw new IllegalArgumentException( + "delta should be a delta to a whole object. " + //$NON-NLS-1$ + type + " cannot be a whole object"); //$NON-NLS-1$ + } + return this; + } + + ReceivedPackStatistics build() { + ReceivedPackStatistics s = new ReceivedPackStatistics(); + s.numBytesRead = numBytesRead; + s.numWholeCommit = numWholeCommit; + s.numWholeTree = numWholeTree; + s.numWholeBlob = numWholeBlob; + s.numWholeTag = numWholeTag; + s.numOfsDelta = numOfsDelta; + s.numRefDelta = numRefDelta; + s.numDeltaCommit = numDeltaCommit; + s.numDeltaTree = numDeltaTree; + s.numDeltaBlob = numDeltaBlob; + s.numDeltaTag = numDeltaTag; + return s; + } + } +} 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 ce5ccaa65d..81c5da3c78 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ServiceMayNotContinueException.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ServiceMayNotContinueException.java @@ -44,6 +44,7 @@ package org.eclipse.jgit.transport; import java.io.IOException; + import javax.servlet.http.HttpServletResponse; import org.eclipse.jgit.internal.JGitText; 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 bc4843a8af..df860695df 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/Transport.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/Transport.java @@ -1199,6 +1199,9 @@ public abstract class Transport implements AutoCloseable { final FetchResult result = new FetchResult(); new FetchProcess(this, toFetch).execute(monitor, result); + + local.autoGC(monitor); + return result; } 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 bbc0d0aa73..9b0834133b 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportBundleFile.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportBundleFile.java @@ -94,7 +94,7 @@ class TransportBundleFile extends Transport implements TransportBundle { public Transport open(URIish uri, Repository local, String remoteName) throws NotSupportedException, TransportException { if ("bundle".equals(uri.getScheme())) { //$NON-NLS-1$ - File path = local.getFS().resolve(new File("."), uri.getPath()); //$NON-NLS-1$ + File path = FS.DETECTED.resolve(new File("."), uri.getPath()); //$NON-NLS-1$ return new TransportBundleFile(local, uri, path); } 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 a7f42fd873..c6e4c50801 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitAnon.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitAnon.java @@ -46,6 +46,7 @@ package org.eclipse.jgit.transport; import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -62,7 +63,6 @@ import org.eclipse.jgit.errors.NotSupportedException; import org.eclipse.jgit.errors.TransportException; import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.lib.Repository; -import org.eclipse.jgit.util.io.SafeBufferedOutputStream; /** * Transport through a git-daemon waiting for anonymous TCP connections. @@ -182,7 +182,7 @@ class TransportGitAnon extends TcpTransport implements PackTransport { OutputStream sOut = sock.getOutputStream(); sIn = new BufferedInputStream(sIn); - sOut = new SafeBufferedOutputStream(sOut); + sOut = new BufferedOutputStream(sOut); init(sIn, sOut); service("git-upload-pack", pckOut); //$NON-NLS-1$ @@ -221,7 +221,7 @@ class TransportGitAnon extends TcpTransport implements PackTransport { OutputStream sOut = sock.getOutputStream(); sIn = new BufferedInputStream(sIn); - sOut = new SafeBufferedOutputStream(sOut); + sOut = new BufferedOutputStream(sOut); init(sIn, sOut); service("git-receive-pack", pckOut); //$NON-NLS-1$ 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 52f0f04562..da98e8c9ea 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitSsh.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportGitSsh.java @@ -64,11 +64,11 @@ import org.eclipse.jgit.errors.TransportException; import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.util.FS; import org.eclipse.jgit.util.QuotedString; import org.eclipse.jgit.util.SystemReader; import org.eclipse.jgit.util.io.MessageWriter; import org.eclipse.jgit.util.io.StreamCopyThread; -import org.eclipse.jgit.util.FS; /** * Transport through an SSH tunnel. 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 1166080f2a..96a6fe1d01 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportHttp.java @@ -45,7 +45,9 @@ package org.eclipse.jgit.transport; +import static org.eclipse.jgit.lib.Constants.HEAD; import static org.eclipse.jgit.util.HttpSupport.ENCODING_GZIP; +import static org.eclipse.jgit.util.HttpSupport.ENCODING_X_GZIP; import static org.eclipse.jgit.util.HttpSupport.HDR_ACCEPT; import static org.eclipse.jgit.util.HttpSupport.HDR_ACCEPT_ENCODING; import static org.eclipse.jgit.util.HttpSupport.HDR_CONTENT_ENCODING; @@ -128,6 +130,25 @@ public class TransportHttp extends HttpTransport implements WalkTransport, private static final String SVC_RECEIVE_PACK = "git-receive-pack"; //$NON-NLS-1$ + /** + * Accept-Encoding header in the HTTP request + * (https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html). + * + * @since 4.6 + */ + public enum AcceptEncoding { + /** + * Do not specify an Accept-Encoding header. In most servers this + * results in the content being transmitted as-is. + */ + UNSPECIFIED, + + /** + * Accept gzip content encoding. + */ + GZIP + } + static final TransportProtocol PROTO_HTTP = new TransportProtocol() { private final String[] schemeNames = { "http", "https" }; //$NON-NLS-1$ //$NON-NLS-2$ @@ -324,12 +345,15 @@ public class TransportHttp extends HttpTransport implements WalkTransport, br.close(); } - if (!refs.containsKey(Constants.HEAD)) { + if (!refs.containsKey(HEAD)) { // If HEAD was not published in the info/refs file (it usually // is not there) download HEAD by itself as a loose file and do // the resolution by hand. // - HttpConnection conn = httpOpen(new URL(baseUrl, Constants.HEAD)); + HttpConnection conn = httpOpen( + METHOD_GET, + new URL(baseUrl, HEAD), + AcceptEncoding.GZIP); int status = HttpSupport.response(conn); switch (status) { case HttpConnection.HTTP_OK: { @@ -341,11 +365,11 @@ public class TransportHttp extends HttpTransport implements WalkTransport, Ref r = refs.get(target); if (r == null) r = new ObjectIdRef.Unpeeled(Ref.Storage.NEW, target, null); - r = new SymbolicRef(Constants.HEAD, r); + r = new SymbolicRef(HEAD, r); refs.put(r.getName(), r); } else if (line != null && ObjectId.isId(line)) { Ref r = new ObjectIdRef.Unpeeled(Ref.Storage.NETWORK, - Constants.HEAD, ObjectId.fromString(line)); + HEAD, ObjectId.fromString(line)); refs.put(r.getName(), r); } } finally { @@ -455,7 +479,7 @@ public class TransportHttp extends HttpTransport implements WalkTransport, Collection<Type> ignoreTypes = null; for (;;) { try { - final HttpConnection conn = httpOpen(u); + final HttpConnection conn = httpOpen(METHOD_GET, u, AcceptEncoding.GZIP); if (useSmartHttp) { String exp = "application/x-" + service + "-advertisement"; //$NON-NLS-1$ //$NON-NLS-2$ conn.setRequestProperty(HDR_ACCEPT, exp + ", */*"); //$NON-NLS-1$ @@ -529,21 +553,37 @@ public class TransportHttp extends HttpTransport implements WalkTransport, } } - final HttpConnection httpOpen(URL u) throws IOException { - return httpOpen(METHOD_GET, u); + /** + * Open an HTTP connection, setting the accept-encoding request header to gzip. + * + * @param method HTTP request method + * @param u url of the HTTP connection + * @return the HTTP connection + * @throws IOException + * @since 3.3 + * @deprecated use {@link #httpOpen(String, URL, AcceptEncoding)} instead. + */ + @Deprecated + protected HttpConnection httpOpen(String method, URL u) throws IOException { + return httpOpen(method, u, AcceptEncoding.GZIP); } /** * Open an HTTP connection. * - * @param method - * @param u - * @return the connection + * @param method HTTP request method + * @param u url of the HTTP connection + * @param acceptEncoding accept-encoding header option + * @return the HTTP connection * @throws IOException - * @since 3.3 + * @since 4.6 */ - protected HttpConnection httpOpen(String method, URL u) - throws IOException { + protected HttpConnection httpOpen(String method, URL u, + AcceptEncoding acceptEncoding) throws IOException { + if (method == null || u == null || acceptEncoding == null) { + throw new NullPointerException(); + } + final Proxy proxy = HttpSupport.proxyFor(proxySelector, u); HttpConnection conn = connectionFactory.create(u, proxy); @@ -553,7 +593,9 @@ public class TransportHttp extends HttpTransport implements WalkTransport, conn.setRequestMethod(method); conn.setUseCaches(false); - conn.setRequestProperty(HDR_ACCEPT_ENCODING, ENCODING_GZIP); + if (acceptEncoding == AcceptEncoding.GZIP) { + conn.setRequestProperty(HDR_ACCEPT_ENCODING, ENCODING_GZIP); + } conn.setRequestProperty(HDR_PRAGMA, "no-cache"); //$NON-NLS-1$ if (UserAgent.get() != null) { conn.setRequestProperty(HDR_USER_AGENT, UserAgent.get()); @@ -575,7 +617,7 @@ public class TransportHttp extends HttpTransport implements WalkTransport, final InputStream openInputStream(HttpConnection conn) throws IOException { InputStream input = conn.getInputStream(); - if (ENCODING_GZIP.equals(conn.getHeaderField(HDR_CONTENT_ENCODING))) + if (isGzipContent(conn)) input = new GZIPInputStream(input); return input; } @@ -591,6 +633,11 @@ public class TransportHttp extends HttpTransport implements WalkTransport, return expType.equals(actType); } + private boolean isGzipContent(final HttpConnection c) { + return ENCODING_GZIP.equals(c.getHeaderField(HDR_CONTENT_ENCODING)) + || ENCODING_X_GZIP.equals(c.getHeaderField(HDR_CONTENT_ENCODING)); + } + private void readSmartHeaders(final InputStream in, final String service) throws IOException { // A smart reply will have a '#' after the first 4 bytes, but @@ -655,6 +702,14 @@ public class TransportHttp extends HttpTransport implements WalkTransport, } @Override + BufferedReader openReader(String path) throws IOException { + // Line oriented readable content is likely to compress well. + // Request gzip encoding. + InputStream is = open(path, AcceptEncoding.GZIP).in; + return new BufferedReader(new InputStreamReader(is, Constants.CHARSET)); + } + + @Override Collection<String> getPackNames() throws IOException { final Collection<String> packs = new ArrayList<String>(); try { @@ -679,14 +734,25 @@ public class TransportHttp extends HttpTransport implements WalkTransport, @Override FileStream open(final String path) throws IOException { + return open(path, AcceptEncoding.UNSPECIFIED); + } + + FileStream open(String path, AcceptEncoding acceptEncoding) + throws IOException { final URL base = httpObjectsUrl; final URL u = new URL(base, path); - final HttpConnection c = httpOpen(u); + final HttpConnection c = httpOpen(METHOD_GET, u, acceptEncoding); switch (HttpSupport.response(c)) { case HttpConnection.HTTP_OK: final InputStream in = openInputStream(c); - final int len = c.getContentLength(); - return new FileStream(in, len); + // If content is being gzipped and then transferred, the content + // length in the header is the zipped content length, not the + // actual content length. + if (!isGzipContent(c)) { + final int len = c.getContentLength(); + return new FileStream(in, len); + } + return new FileStream(in); case HttpConnection.HTTP_NOT_FOUND: throw new FileNotFoundException(u.toString()); default: @@ -832,7 +898,10 @@ public class TransportHttp extends HttpTransport implements WalkTransport, } void openStream() throws IOException { - conn = httpOpen(METHOD_POST, new URL(baseUrl, serviceName)); + conn = httpOpen( + METHOD_POST, + new URL(baseUrl, serviceName), + AcceptEncoding.GZIP); conn.setInstanceFollowRedirects(false); conn.setDoOutput(true); conn.setRequestProperty(HDR_CONTENT_TYPE, requestType); 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 292ba7ed8a..1528c71426 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportLocal.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportLocal.java @@ -48,6 +48,7 @@ package org.eclipse.jgit.transport; import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -67,7 +68,6 @@ import org.eclipse.jgit.transport.resolver.ReceivePackFactory; import org.eclipse.jgit.transport.resolver.UploadPackFactory; import org.eclipse.jgit.util.FS; import org.eclipse.jgit.util.io.MessageWriter; -import org.eclipse.jgit.util.io.SafeBufferedOutputStream; import org.eclipse.jgit.util.io.StreamCopyThread; /** @@ -258,7 +258,7 @@ class TransportLocal extends Transport implements PackTransport { OutputStream upOut = uploadPack.getOutputStream(); upIn = new BufferedInputStream(upIn); - upOut = new SafeBufferedOutputStream(upOut); + upOut = new BufferedOutputStream(upOut); init(upIn, upOut); readAdvertisedRefs(); @@ -311,7 +311,7 @@ class TransportLocal extends Transport implements PackTransport { OutputStream rpOut = receivePack.getOutputStream(); rpIn = new BufferedInputStream(rpIn); - rpOut = new SafeBufferedOutputStream(rpOut); + rpOut = new BufferedOutputStream(rpOut); init(rpIn, rpOut); readAdvertisedRefs(); 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 d1fd67e977..201fb18740 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java @@ -45,8 +45,8 @@ package org.eclipse.jgit.transport; import static org.eclipse.jgit.lib.RefDatabase.ALL; import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_AGENT; -import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_ALLOW_TIP_SHA1_IN_WANT; import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_ALLOW_REACHABLE_SHA1_IN_WANT; +import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_ALLOW_TIP_SHA1_IN_WANT; import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_INCLUDE_TAG; import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_MULTI_ACK; import static org.eclipse.jgit.transport.GitProtocolConstants.OPTION_MULTI_ACK_DETAILED; @@ -313,6 +313,7 @@ public class UploadPack { private PackStatistics statistics; + @SuppressWarnings("deprecation") private UploadPackLogger logger = UploadPackLogger.NULL; /** @@ -1428,6 +1429,7 @@ public class UploadPack { } } + @SuppressWarnings("deprecation") private void sendPack(final boolean sideband) throws IOException { ProgressMonitor pm = NullProgressMonitor.INSTANCE; OutputStream packOut = rawOut; 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 85ebecc450..0588634d2a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPackLogger.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPackLogger.java @@ -56,7 +56,7 @@ import org.eclipse.jgit.internal.storage.pack.PackWriter; * @deprecated use {@link PostUploadHook} instead */ @Deprecated -public interface UploadPackLogger { +public interface UploadPackLogger { // TODO remove in JGit 5.0 /** A simple no-op logger. */ public static final UploadPackLogger NULL = new UploadPackLogger() { public void onPackStatistics(PackWriter.Statistics 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 fe03bdc867..4c3fdd84f2 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkEncryption.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkEncryption.java @@ -143,35 +143,6 @@ abstract class WalkEncryption { } } - // PBEParameterSpec factory for Java (version <= 7). - // Does not support AlgorithmParameterSpec. - static PBEParameterSpec java7PBEParameterSpec(byte[] salt, - int iterationCount) { - return new PBEParameterSpec(salt, iterationCount); - } - - // PBEParameterSpec factory for Java (version >= 8). - // Adds support for AlgorithmParameterSpec. - static PBEParameterSpec java8PBEParameterSpec(byte[] salt, - int iterationCount, AlgorithmParameterSpec paramSpec) { - try { - @SuppressWarnings("boxing") - PBEParameterSpec instance = PBEParameterSpec.class - .getConstructor(byte[].class, int.class, - AlgorithmParameterSpec.class) - .newInstance(salt, iterationCount, paramSpec); - return instance; - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - // Current runtime version. - // https://docs.oracle.com/javase/7/docs/technotes/guides/versioning/spec/versioning2.html - static double javaVersion() { - return Double.parseDouble(System.getProperty("java.specification.version")); //$NON-NLS-1$ - } - /** * JetS3t compatibility reference: <a href= * "https://bitbucket.org/jmurty/jets3t/src/156c00eb160598c2e9937fd6873f00d3190e28ca/src/org/jets3t/service/security/EncryptionUtil.java"> @@ -204,7 +175,7 @@ abstract class WalkEncryption { // Size 16, see com.sun.crypto.provider.AESConstants.AES_BLOCK_SIZE static final byte[] ZERO_AES_IV = new byte[16]; - private static final String cryptoVer = VERSION; + private static final String CRYPTO_VER = VERSION; private final String cryptoAlg; @@ -217,7 +188,7 @@ abstract class WalkEncryption { cryptoAlg = algo; // Verify if cipher is present. - Cipher cipher = Cipher.getInstance(cryptoAlg); + Cipher cipher = InsecureCipherFactory.create(cryptoAlg); // Standard names are not case-sensitive. // http://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html @@ -233,9 +204,7 @@ abstract class WalkEncryption { boolean useIV = cryptoName.contains("AES"); //$NON-NLS-1$ // PBEParameterSpec algorithm parameters are supported from Java 8. - boolean isJava8 = javaVersion() >= 1.8; - - if (useIV && isJava8) { + if (useIV) { // Support IV where possible: // * since JCE provider uses random IV for PBE/AES // * and there is no place to store dynamic IV in JetS3t V2 @@ -245,34 +214,33 @@ abstract class WalkEncryption { // https://bitbucket.org/jmurty/jets3t/raw/156c00eb160598c2e9937fd6873f00d3190e28ca/src/org/jets3t/service/security/EncryptionUtil.java // http://cr.openjdk.java.net/~mullan/webrevs/ascarpin/webrev.00/raw_files/new/src/share/classes/com/sun/crypto/provider/PBES2Core.java IvParameterSpec paramIV = new IvParameterSpec(ZERO_AES_IV); - paramSpec = java8PBEParameterSpec(SALT, ITERATIONS, paramIV); + paramSpec = new PBEParameterSpec(SALT, ITERATIONS, paramIV); } else { // Strict legacy JetS3t V2 compatibility, with no IV support. - paramSpec = java7PBEParameterSpec(SALT, ITERATIONS); + paramSpec = new PBEParameterSpec(SALT, ITERATIONS); } // Verify if cipher + key are allowed by policy. cipher.init(Cipher.ENCRYPT_MODE, secretKey, paramSpec); cipher.doFinal(); - } @Override void request(final HttpURLConnection u, final String prefix) { - u.setRequestProperty(prefix + JETS3T_CRYPTO_VER, cryptoVer); + u.setRequestProperty(prefix + JETS3T_CRYPTO_VER, CRYPTO_VER); u.setRequestProperty(prefix + JETS3T_CRYPTO_ALG, cryptoAlg); } @Override void validate(final HttpURLConnection u, final String prefix) throws IOException { - validateImpl(u, prefix, cryptoVer, cryptoAlg); + validateImpl(u, prefix, CRYPTO_VER, cryptoAlg); } @Override OutputStream encrypt(final OutputStream os) throws IOException { try { - final Cipher cipher = Cipher.getInstance(cryptoAlg); + final Cipher cipher = InsecureCipherFactory.create(cryptoAlg); cipher.init(Cipher.ENCRYPT_MODE, secretKey, paramSpec); return new CipherOutputStream(os, cipher); } catch (GeneralSecurityException e) { @@ -283,7 +251,7 @@ abstract class WalkEncryption { @Override InputStream decrypt(final InputStream in) throws IOException { try { - final Cipher cipher = Cipher.getInstance(cryptoAlg); + final Cipher cipher = InsecureCipherFactory.create(cryptoAlg); cipher.init(Cipher.DECRYPT_MODE, secretKey, paramSpec); return new CipherInputStream(in, cipher); } catch (GeneralSecurityException e) { @@ -374,7 +342,7 @@ abstract class WalkEncryption { String keySalt = props.getProperty(profile + X_KEY_SALT, DEFAULT_KEY_SALT); // Verify if cipher is present. - Cipher cipher = Cipher.getInstance(cipherAlgo); + Cipher cipher = InsecureCipherFactory.create(cipherAlgo); // Verify if key factory is present. SecretKeyFactory factory = SecretKeyFactory.getInstance(keyAlgo); @@ -432,7 +400,7 @@ abstract class WalkEncryption { @Override OutputStream encrypt(OutputStream output) throws IOException { try { - Cipher cipher = Cipher.getInstance(cipherAlgo); + Cipher cipher = InsecureCipherFactory.create(cipherAlgo); cipher.init(Cipher.ENCRYPT_MODE, secretKey); AlgorithmParameters params = cipher.getParameters(); if (params == null) { @@ -489,7 +457,7 @@ abstract class WalkEncryption { JGitText.get().unsupportedEncryptionVersion, vers)); } try { - decryptCipher = Cipher.getInstance(cipherAlgo); + decryptCipher = InsecureCipherFactory.create(cipherAlgo); if (cont.isEmpty()) { decryptCipher.init(Cipher.DECRYPT_MODE, secretKey); } else { 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 17edfdc4fb..13d4a24b02 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkFetchConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkFetchConnection.java @@ -195,7 +195,7 @@ class WalkFetchConnection extends BaseFetchConnection { local = wt.local; objCheck = wt.getObjectChecker(); inserter = local.newObjectInserter(); - reader = local.newObjectReader(); + reader = inserter.newReader(); remotes = new ArrayList<WalkRemoteObjectDatabase>(); remotes.add(w); @@ -240,6 +240,12 @@ class WalkFetchConnection extends BaseFetchConnection { downloadObject(monitor, id); process(id); } + + try { + inserter.flush(); + } catch (IOException e) { + throw new TransportException(e.getMessage(), e); + } } public Collection<PackLock> getPackLocks() { @@ -652,7 +658,6 @@ class WalkFetchConnection extends BaseFetchConnection { Constants.typeString(type), Integer.valueOf(compressed.length))); } - inserter.flush(); } private Collection<WalkRemoteObjectDatabase> expandOneAlternate( @@ -876,14 +881,17 @@ class WalkFetchConnection extends BaseFetchConnection { void downloadPack(final ProgressMonitor monitor) throws IOException { String name = "pack/" + packName; //$NON-NLS-1$ WalkRemoteObjectDatabase.FileStream s = connection.open(name); - PackParser parser = inserter.newPackParser(s.in); - parser.setAllowThin(false); - parser.setObjectChecker(objCheck); - parser.setLockMessage(lockMessage); - PackLock lock = parser.parse(monitor); - if (lock != null) - packLocks.add(lock); - inserter.flush(); + try { + PackParser parser = inserter.newPackParser(s.in); + parser.setAllowThin(false); + parser.setObjectChecker(objCheck); + parser.setLockMessage(lockMessage); + PackLock lock = parser.parse(monitor); + if (lock != null) + packLocks.add(lock); + } finally { + s.in.close(); + } } } } 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 4eaf3f9d8a..7b449c752a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkPushConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkPushConnection.java @@ -45,6 +45,7 @@ package org.eclipse.jgit.transport; import static org.eclipse.jgit.transport.WalkRemoteObjectDatabase.ROOT_DIR; +import java.io.BufferedOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; @@ -69,7 +70,6 @@ import org.eclipse.jgit.lib.Ref.Storage; import org.eclipse.jgit.lib.RefWriter; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.transport.RemoteRefUpdate.Status; -import org.eclipse.jgit.util.io.SafeBufferedOutputStream; /** * Generic push support for dumb transport protocols. @@ -262,21 +262,15 @@ class WalkPushConnection extends BaseConnection implements PushConnection { // Write the pack file, then the index, as readers look the // other direction (index, then pack file). // - final String wt = "Put " + base.substring(0, 12); //$NON-NLS-1$ - OutputStream os = dest.writeFile(pathPack, monitor, wt + "..pack"); //$NON-NLS-1$ - try { - os = new SafeBufferedOutputStream(os); + String wt = "Put " + base.substring(0, 12); //$NON-NLS-1$ + try (OutputStream os = new BufferedOutputStream( + dest.writeFile(pathPack, monitor, wt + "..pack"))) { //$NON-NLS-1$ writer.writePack(monitor, monitor, os); - } finally { - os.close(); } - os = dest.writeFile(pathIdx, monitor, wt + "..idx"); //$NON-NLS-1$ - try { - os = new SafeBufferedOutputStream(os); + try (OutputStream os = new BufferedOutputStream( + dest.writeFile(pathIdx, monitor, wt + "..idx"))) { //$NON-NLS-1$ writer.writeIndex(os); - } finally { - os.close(); } // Record the pack at the start of the pack info list. This 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 e47913ea39..24f30ed206 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkRemoteObjectDatabase.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkRemoteObjectDatabase.java @@ -133,6 +133,9 @@ abstract class WalkRemoteObjectDatabase { * Callers such as {@link WalkFetchConnection} are prepared to handle this * by validating the content received, and assuming content that fails to * match its hash is an incorrectly phrased FileNotFoundException. + * <p> + * This method is recommended for already compressed files like loose objects + * and pack files. For text files, see {@link #openReader(String)}. * * @param path * location of the file to read, relative to this objects @@ -346,8 +349,8 @@ abstract class WalkRemoteObjectDatabase { /** * Open a buffered reader around a file. * <p> - * This is shorthand for calling {@link #open(String)} and then wrapping it - * in a reader suitable for line oriented files like the alternates list. + * This method is suitable for for reading line-oriented resources like + * <code>info/packs</code>, <code>info/refs</code>, and the alternates list. * * @return a stream to read from the file. Never null. * @param path diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/AbstractTreeIterator.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/AbstractTreeIterator.java index 07fc829db4..6d4c342284 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/AbstractTreeIterator.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/AbstractTreeIterator.java @@ -49,8 +49,8 @@ import java.io.IOException; import java.nio.ByteBuffer; import java.nio.CharBuffer; -import org.eclipse.jgit.attributes.AttributesNode; import org.eclipse.jgit.attributes.AttributesHandler; +import org.eclipse.jgit.attributes.AttributesNode; import org.eclipse.jgit.dircache.DirCacheCheckout; import org.eclipse.jgit.errors.CorruptObjectException; import org.eclipse.jgit.errors.IncorrectObjectTypeException; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/FileTreeIterator.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/FileTreeIterator.java index db81e1af9b..afa2ed9cb8 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/FileTreeIterator.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/FileTreeIterator.java @@ -426,4 +426,9 @@ public class FileTreeIterator extends WorkingTreeIterator { protected byte[] idSubmodule(final Entry e) { return idSubmodule(getDirectory(), e); } + + @Override + protected String readSymlinkTarget(Entry entry) throws IOException { + return fs.readSymLink(getEntryFile()); + } } 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 911b7ffa1a..5dfebe9ca7 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/TreeWalk.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/TreeWalk.java @@ -53,10 +53,11 @@ import org.eclipse.jgit.annotations.Nullable; import org.eclipse.jgit.api.errors.JGitInternalException; import org.eclipse.jgit.attributes.Attribute; import org.eclipse.jgit.attributes.Attributes; +import org.eclipse.jgit.attributes.AttributesHandler; import org.eclipse.jgit.attributes.AttributesNodeProvider; import org.eclipse.jgit.attributes.AttributesProvider; +import org.eclipse.jgit.attributes.FilterCommandRegistry; import org.eclipse.jgit.dircache.DirCacheBuildIterator; -import org.eclipse.jgit.attributes.AttributesHandler; import org.eclipse.jgit.dircache.DirCacheIterator; import org.eclipse.jgit.errors.CorruptObjectException; import org.eclipse.jgit.errors.IncorrectObjectTypeException; @@ -64,6 +65,7 @@ import org.eclipse.jgit.errors.MissingObjectException; import org.eclipse.jgit.errors.StopWalkException; import org.eclipse.jgit.lib.AnyObjectId; import org.eclipse.jgit.lib.Config; +import org.eclipse.jgit.lib.ConfigConstants; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.CoreConfig.EolStreamType; import org.eclipse.jgit.lib.FileMode; @@ -313,6 +315,8 @@ public class TreeWalk implements AutoCloseable, AttributesProvider { private Config config; + private Set<String> filterCommands; + /** * Create a new tree walker for a given repository. * @@ -357,6 +361,8 @@ public class TreeWalk implements AutoCloseable, AttributesProvider { if (repo != null) { config = repo.getConfig(); attributesNodeProvider = repo.createAttributesNodeProvider(); + filterCommands = FilterCommandRegistry + .getRegisteredFilterCommands(); } else { config = null; attributesNodeProvider = null; @@ -1367,10 +1373,22 @@ public class TreeWalk implements AutoCloseable, AttributesProvider { String filterCommand = filterCommandsByNameDotType.get(key); if (filterCommand != null) return filterCommand; - filterCommand = config.getString(Constants.ATTR_FILTER, + filterCommand = config.getString(ConfigConstants.CONFIG_FILTER_SECTION, filterDriverName, filterCommandType); - if (filterCommand != null) + boolean useBuiltin = config.getBoolean( + ConfigConstants.CONFIG_FILTER_SECTION, + filterDriverName, ConfigConstants.CONFIG_KEY_USEJGITBUILTIN, false); + if (useBuiltin) { + String builtinFilterCommand = Constants.BUILTIN_FILTER_PREFIX + + filterDriverName + '/' + filterCommandType; + if (filterCommands != null + && filterCommands.contains(builtinFilterCommand)) { + filterCommand = builtinFilterCommand; + } + } + if (filterCommand != null) { filterCommandsByNameDotType.put(key, filterCommand); + } return filterCommand; } } 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 9a3fa8060b..52477cb573 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java @@ -65,6 +65,8 @@ import java.util.Comparator; import org.eclipse.jgit.api.errors.FilterFailedException; import org.eclipse.jgit.attributes.AttributesNode; import org.eclipse.jgit.attributes.AttributesRule; +import org.eclipse.jgit.attributes.FilterCommand; +import org.eclipse.jgit.attributes.FilterCommandRegistry; import org.eclipse.jgit.diff.RawText; import org.eclipse.jgit.dircache.DirCache; import org.eclipse.jgit.dircache.DirCacheEntry; @@ -93,6 +95,8 @@ import org.eclipse.jgit.util.Holder; import org.eclipse.jgit.util.IO; import org.eclipse.jgit.util.Paths; import org.eclipse.jgit.util.RawParseUtils; +import org.eclipse.jgit.util.TemporaryBuffer; +import org.eclipse.jgit.util.TemporaryBuffer.LocalFile; import org.eclipse.jgit.util.io.AutoLFInputStream; import org.eclipse.jgit.util.io.EolStreamTypeUtil; @@ -263,7 +267,6 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator { // If there is a matching DirCacheIterator, we can reuse // its idBuffer, but only if we appear to be clean against // the cached index information for the path. - // DirCacheIterator i = state.walk.getTree(state.dirCacheTree, DirCacheIterator.class); if (i != null) { @@ -393,15 +396,9 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator { if (len <= MAXIMUM_FILE_SIZE_TO_READ_FULLY) { ByteBuffer rawbuf = IO.readWholeStream(is, (int) len); - byte[] raw = rawbuf.array(); - int n = rawbuf.limit(); - if (!isBinary(raw, n)) { - rawbuf = filterClean(raw, n, opType); - raw = rawbuf.array(); - n = rawbuf.limit(); - } - canonLen = n; - return new ByteArrayInputStream(raw, 0, n); + rawbuf = filterClean(rawbuf.array(), rawbuf.limit(), opType); + canonLen = rawbuf.limit(); + return new ByteArrayInputStream(rawbuf.array(), 0, (int) canonLen); } if (getCleanFilterCommand() == null && isBinary(e)) { @@ -429,10 +426,6 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator { } } - private static boolean isBinary(byte[] content, int sz) { - return RawText.isBinary(content, sz); - } - private static boolean isBinary(Entry entry) throws IOException { InputStream in = entry.openInputStream(); try { @@ -461,6 +454,16 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator { in = handleAutoCRLF(in, opType); String filterCommand = getCleanFilterCommand(); if (filterCommand != null) { + if (FilterCommandRegistry.isRegistered(filterCommand)) { + LocalFile buffer = new TemporaryBuffer.LocalFile(null); + FilterCommand command = FilterCommandRegistry + .createFilterCommand(filterCommand, repository, in, + buffer); + while (command.run() != -1) { + // loop as long as command.run() tells there is work to do + } + return buffer.openInputStream(); + } FS fs = repository.getFS(); ProcessBuilder filterProcessBuilder = fs.runInShell(filterCommand, new String[0]); @@ -1005,10 +1008,10 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator { return false; } else { - if (mode == FileMode.SYMLINK.getBits()) - return !new File(readContentAsNormalizedString(current())) - .equals(new File((readContentAsNormalizedString(entry, - reader)))); + if (mode == FileMode.SYMLINK.getBits()) { + return !new File(readSymlinkTarget(current())).equals( + new File(readContentAsNormalizedString(entry, reader))); + } // Content differs: that's a real change, perhaps if (reader == null) // deprecated use, do no further checks return true; @@ -1054,12 +1057,30 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator { return FS.detect().normalize(RawParseUtils.decode(cachedBytes)); } - private static String readContentAsNormalizedString(Entry entry) throws IOException { + /** + * Reads the target of a symlink as a string. This default implementation + * fully reads the entry's input stream and converts it to a normalized + * string. Subclasses may override to provide more specialized + * implementations. + * + * @param entry + * to read + * @return the entry's content as a normalized string + * @throws IOException + * if the entry cannot be read or does not denote a symlink + * @since 4.6 + */ + protected String readSymlinkTarget(Entry entry) throws IOException { + if (!entry.getMode().equals(FileMode.SYMLINK)) { + throw new java.nio.file.NotLinkException(entry.getName()); + } long length = entry.getLength(); byte[] content = new byte[(int) length]; - InputStream is = entry.openInputStream(); - IO.readFully(is, content, 0, (int) length); - return FS.detect().normalize(RawParseUtils.decode(content)); + try (InputStream is = entry.openInputStream()) { + int bytesRead = IO.readFully(is, content, 0); + return FS.detect() + .normalize(RawParseUtils.decode(content, 0, bytesRead)); + } } private static long computeLength(InputStream in) throws IOException { 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 dea07c1973..112ce8fb9f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeOptions.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeOptions.java @@ -44,8 +44,8 @@ package org.eclipse.jgit.treewalk; import org.eclipse.jgit.lib.Config; -import org.eclipse.jgit.lib.ConfigConstants; import org.eclipse.jgit.lib.Config.SectionParser; +import org.eclipse.jgit.lib.ConfigConstants; import org.eclipse.jgit.lib.CoreConfig.AutoCRLF; import org.eclipse.jgit.lib.CoreConfig.CheckStat; import org.eclipse.jgit.lib.CoreConfig.EOL; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/ChangeIdUtil.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/ChangeIdUtil.java index e14096e598..f1f6053e3b 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/ChangeIdUtil.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/ChangeIdUtil.java @@ -45,8 +45,8 @@ package org.eclipse.jgit.util; import java.util.regex.Pattern; import org.eclipse.jgit.lib.Constants; -import org.eclipse.jgit.lib.ObjectInserter; import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.lib.ObjectInserter; import org.eclipse.jgit.lib.PersonIdent; /** 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 a55b5c0ac5..dcd7970cbc 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java @@ -164,7 +164,7 @@ public abstract class FS { /** The auto-detected implementation selected for this operating system and JRE. */ public static final FS DETECTED = detect(); - private static FSFactory factory; + private volatile static FSFactory factory; /** * Auto-detect the appropriate file system abstraction. 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 202645b9d9..251381ab33 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/HttpSupport.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/HttpSupport.java @@ -144,6 +144,12 @@ public class HttpSupport { /** The {@code gzip} encoding value for {@link #HDR_ACCEPT_ENCODING}. */ public static final String ENCODING_GZIP = "gzip"; //$NON-NLS-1$ + /** + * The {@code x-gzip} encoding value for {@link #HDR_ACCEPT_ENCODING}. + * @since 4.6 + */ + public static final String ENCODING_X_GZIP = "x-gzip"; //$NON-NLS-1$ + /** The standard {@code text/plain} MIME type. */ public static final String TEXT_PLAIN = "text/plain"; //$NON-NLS-1$ 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 9860ef070f..b36fc2391a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/SystemReader.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/SystemReader.java @@ -56,10 +56,12 @@ import java.text.SimpleDateFormat; import java.util.Locale; import java.util.TimeZone; -import org.eclipse.jgit.storage.file.FileBasedConfig; import org.eclipse.jgit.errors.CorruptObjectException; import org.eclipse.jgit.lib.Config; import org.eclipse.jgit.lib.ObjectChecker; +import org.eclipse.jgit.storage.file.FileBasedConfig; +import org.eclipse.jgit.util.time.MonotonicClock; +import org.eclipse.jgit.util.time.MonotonicSystemClock; /** * Interface to read values from the system. @@ -231,6 +233,14 @@ public abstract class SystemReader { public abstract long getCurrentTime(); /** + * @return clock instance preferred by this system. + * @since 4.6 + */ + public MonotonicClock getClock() { + return new MonotonicSystemClock(); + } + + /** * @param when TODO * @return the local time zone */ 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 3cd5929c7f..57bcfbd5e5 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/TemporaryBuffer.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/TemporaryBuffer.java @@ -56,7 +56,6 @@ import java.util.ArrayList; import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.lib.NullProgressMonitor; import org.eclipse.jgit.lib.ProgressMonitor; -import org.eclipse.jgit.util.io.SafeBufferedOutputStream; /** * A fully buffered output stream. @@ -360,7 +359,7 @@ public abstract class TemporaryBuffer extends OutputStream { overflow.write(b.buffer, 0, b.count); blocks = null; - overflow = new SafeBufferedOutputStream(overflow, Block.SZ); + overflow = new BufferedOutputStream(overflow, Block.SZ); overflow.write(last.buffer, 0, last.count); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/IsolatedOutputStream.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/IsolatedOutputStream.java new file mode 100644 index 0000000000..3598a7ba87 --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/IsolatedOutputStream.java @@ -0,0 +1,243 @@ +/* + * Copyright (C) 2016, 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.io; + +import java.io.IOException; +import java.io.InterruptedIOException; +import java.io.OutputStream; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Future; +import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicInteger; + +import org.eclipse.jgit.internal.JGitText; + +/** + * OutputStream isolated from interrupts. + * <p> + * Wraps an OutputStream to prevent interrupts during writes from being made + * visible to that stream instance. This works around buggy or difficult + * OutputStream implementations like JSch that cannot gracefully handle an + * interrupt during write. + * <p> + * Every write (or flush) requires a context switch to another thread. Callers + * should wrap this stream with {@code BufferedOutputStream} using a suitable + * buffer size to amortize the cost of context switches. + * + * @since 4.6 + */ +public class IsolatedOutputStream extends OutputStream { + private final OutputStream dst; + private final ExecutorService copier; + private Future<Void> pending; + + /** + * Wraps an OutputStream. + * + * @param out + * stream to send all writes to. + */ + public IsolatedOutputStream(OutputStream out) { + dst = out; + copier = new ThreadPoolExecutor(1, 1, 0, TimeUnit.MILLISECONDS, + new ArrayBlockingQueue<Runnable>(1), new NamedThreadFactory()); + } + + @Override + public void write(int ch) throws IOException { + write(new byte[] { (byte) ch }, 0, 1); + } + + @Override + public void write(final byte[] buf, final int pos, final int cnt) + throws IOException { + checkClosed(); + execute(new Callable<Void>() { + @Override + public Void call() throws IOException { + dst.write(buf, pos, cnt); + return null; + } + }); + } + + @Override + public void flush() throws IOException { + checkClosed(); + execute(new Callable<Void>() { + @Override + public Void call() throws IOException { + dst.flush(); + return null; + } + }); + } + + @Override + public void close() throws IOException { + if (!copier.isShutdown()) { + try { + if (pending == null || tryCleanClose()) { + cleanClose(); + } else { + dirtyClose(); + } + } finally { + copier.shutdown(); + } + } + } + + private boolean tryCleanClose() { + /* + * If the caller stopped waiting for a prior write or flush, they could + * be trying to close a stream that is still in-use. Check if the prior + * operation ended in a predictable way. + */ + try { + pending.get(0, TimeUnit.MILLISECONDS); + pending = null; + return true; + } catch (TimeoutException | InterruptedException e) { + return false; + } catch (ExecutionException e) { + pending = null; + return true; + } + } + + private void cleanClose() throws IOException { + execute(new Callable<Void>() { + @Override + public Void call() throws IOException { + dst.close(); + return null; + } + }); + } + + private void dirtyClose() throws IOException { + /* + * Interrupt any still pending write or flush operation. This may cause + * massive failures inside of the stream, but its going to be closed as + * the next step. + */ + pending.cancel(true); + + Future<Void> close; + try { + close = copier.submit(new Callable<Void>() { + @Override + public Void call() throws IOException { + dst.close(); + return null; + } + }); + } catch (RejectedExecutionException e) { + throw new IOException(e); + } + try { + close.get(200, TimeUnit.MILLISECONDS); + } catch (InterruptedException | TimeoutException e) { + close.cancel(true); + throw new IOException(e); + } catch (ExecutionException e) { + throw new IOException(e.getCause()); + } + } + + private void checkClosed() throws IOException { + if (copier.isShutdown()) { + throw new IOException(JGitText.get().closed); + } + } + + private void execute(Callable<Void> task) throws IOException { + if (pending != null) { + // Check (and rethrow) any prior failed operation. + checkedGet(pending); + } + try { + pending = copier.submit(task); + } catch (RejectedExecutionException e) { + throw new IOException(e); + } + checkedGet(pending); + pending = null; + } + + private static void checkedGet(Future<Void> future) throws IOException { + try { + future.get(); + } catch (InterruptedException e) { + throw interrupted(e); + } catch (ExecutionException e) { + throw new IOException(e.getCause()); + } + } + + private static InterruptedIOException interrupted(InterruptedException c) { + InterruptedIOException e = new InterruptedIOException(); + e.initCause(c); + return e; + } + + private static class NamedThreadFactory implements ThreadFactory { + private static final AtomicInteger cnt = new AtomicInteger(); + + @Override + public Thread newThread(Runnable r) { + int n = cnt.incrementAndGet(); + String name = IsolatedOutputStream.class.getSimpleName() + '-' + n; + return new Thread(r, name); + } + } +} diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/SafeBufferedOutputStream.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/SafeBufferedOutputStream.java index 68f250da09..84c339889b 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/SafeBufferedOutputStream.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/SafeBufferedOutputStream.java @@ -43,20 +43,13 @@ package org.eclipse.jgit.util.io; import java.io.BufferedOutputStream; -import java.io.IOException; import java.io.OutputStream; /** - * A BufferedOutputStream that throws an error if the final flush fails on - * close. - * <p> - * Java's BufferedOutputStream swallows errors that occur when the output stream - * tries to write the final bytes to the output during close. This may result in - * corrupted files without notice. - * </p> + * @deprecated use BufferedOutputStream in Java 8 and later. */ +@Deprecated public class SafeBufferedOutputStream extends BufferedOutputStream { - /** * @see BufferedOutputStream#BufferedOutputStream(OutputStream) * @param out @@ -76,13 +69,4 @@ public class SafeBufferedOutputStream extends BufferedOutputStream { public SafeBufferedOutputStream(OutputStream out, int size) { super(out, size); } - - @Override - public void close() throws IOException { - try { - flush(); - } finally { - super.close(); - } - } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/StreamCopyThread.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/StreamCopyThread.java index 8d39a22ac2..7aba0a583d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/StreamCopyThread.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/StreamCopyThread.java @@ -47,7 +47,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.InterruptedIOException; import java.io.OutputStream; -import java.util.concurrent.atomic.AtomicInteger; /** Thread to copy from an input stream to an output stream. */ public class StreamCopyThread extends Thread { @@ -59,7 +58,8 @@ public class StreamCopyThread extends Thread { private volatile boolean done; - private final AtomicInteger flushCount = new AtomicInteger(0); + /** Lock held by flush to avoid interrupting a write. */ + private final Object writeLock; /** * Create a thread to copy data from an input stream to an output stream. @@ -75,6 +75,7 @@ public class StreamCopyThread extends Thread { setName(Thread.currentThread().getName() + "-StreamCopy"); //$NON-NLS-1$ src = i; dst = o; + writeLock = new Object(); } /** @@ -84,9 +85,11 @@ public class StreamCopyThread extends Thread { * happen at some future point in time, when the thread wakes up to process * the request. */ + @Deprecated public void flush() { - flushCount.incrementAndGet(); - interrupt(); + synchronized (writeLock) { + interrupt(); + } } /** @@ -113,25 +116,23 @@ public class StreamCopyThread extends Thread { public void run() { try { final byte[] buf = new byte[BUFFER_SIZE]; - int flushCountBeforeRead = 0; boolean readInterrupted = false; for (;;) { try { if (readInterrupted) { - dst.flush(); - readInterrupted = false; - if (!flushCount.compareAndSet(flushCountBeforeRead, 0)) { - // There was a flush() call since last blocked read. - // Set interrupt status, so next blocked read will throw - // an InterruptedIOException and we will flush again. - interrupt(); + synchronized (writeLock) { + boolean interruptedAgain = Thread.interrupted(); + dst.flush(); + if (interruptedAgain) { + interrupt(); + } } + readInterrupted = false; } if (done) break; - flushCountBeforeRead = flushCount.get(); final int n; try { n = src.read(buf); @@ -142,20 +143,12 @@ public class StreamCopyThread extends Thread { if (n < 0) break; - boolean writeInterrupted = false; - for (;;) { - try { - dst.write(buf, 0, n); - } catch (InterruptedIOException wakey) { - writeInterrupted = true; - continue; - } - - // set interrupt status, which will be checked - // when we block in src.read - if (writeInterrupted || flushCount.get() > 0) + synchronized (writeLock) { + boolean writeInterrupted = Thread.interrupted(); + dst.write(buf, 0, n); + if (writeInterrupted) { interrupt(); - break; + } } } catch (IOException e) { break; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/time/MonotonicClock.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/time/MonotonicClock.java new file mode 100644 index 0000000000..794d851903 --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/time/MonotonicClock.java @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2016, 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.time; + +import java.time.Duration; +import java.util.concurrent.TimeUnit; + +/** + * A provider of time. + * <p> + * Clocks should provide wall clock time, obtained from a reasonable clock + * source, such as the local system clock. + * <p> + * MonotonicClocks provide the following behavior, with the assertion always + * being true if {@link ProposedTimestamp#blockUntil(Duration)} is used: + * + * <pre> + * MonotonicClock clk = ...; + * long r1; + * try (ProposedTimestamp t1 = clk.propose()) { + * r1 = t1.millis(); + * t1.blockUntil(...); + * } + * + * try (ProposedTimestamp t2 = clk.propose()) { + * assert t2.millis() > r1; + * } + * </pre> + * + * @since 4.6 + */ +public interface MonotonicClock { + /** + * Obtain a timestamp close to "now". + * <p> + * Proposed times are close to "now", but may not yet be certainly in the + * past. This allows the calling thread to interleave other useful work + * while waiting for the clock instance to create an assurance it will never + * in the future propose a time earlier than the returned time. + * <p> + * A hypothetical implementation could read the local system clock (managed + * by NTP) and return that proposal, concurrently sending network messages + * to closely collaborating peers in the same cluster to also ensure their + * system clocks are ahead of this time. In such an implementation the + * {@link ProposedTimestamp#blockUntil(Duration)} method would wait for + * replies from the peers indicating their own system clocks have moved past + * the proposed time. + * + * @return "now". The value can be immediately accessed by + * {@link ProposedTimestamp#read(TimeUnit)} and friends, but the + * caller must use {@link ProposedTimestamp#blockUntil(Duration)} to + * ensure ordering holds. + */ + ProposedTimestamp propose(); +} diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/time/MonotonicSystemClock.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/time/MonotonicSystemClock.java new file mode 100644 index 0000000000..a9f483063c --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/time/MonotonicSystemClock.java @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2016, 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.time; + +import static java.util.concurrent.TimeUnit.MICROSECONDS; +import static java.util.concurrent.TimeUnit.MILLISECONDS; + +import java.time.Duration; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicLong; + +/** + * A {@link MonotonicClock} based on {@code System.currentTimeMillis}. + * + * @since 4.6 + */ +public class MonotonicSystemClock implements MonotonicClock { + private static final AtomicLong before = new AtomicLong(); + + private static long nowMicros() { + long now = MILLISECONDS.toMicros(System.currentTimeMillis()); + for (;;) { + long o = before.get(); + long n = Math.max(o + 1, now); + if (before.compareAndSet(o, n)) { + return n; + } + } + } + + @Override + public ProposedTimestamp propose() { + final long u = nowMicros(); + return new ProposedTimestamp() { + @Override + public long read(TimeUnit unit) { + return unit.convert(u, MICROSECONDS); + } + + @Override + public void blockUntil(Duration maxWait) { + // Assume system clock never goes backwards. + } + }; + } +} diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/time/ProposedTimestamp.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/time/ProposedTimestamp.java new file mode 100644 index 0000000000..c09ab32b68 --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/time/ProposedTimestamp.java @@ -0,0 +1,176 @@ +/* + * Copyright (C) 2016, 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.time; + +import static java.util.concurrent.TimeUnit.MICROSECONDS; +import static java.util.concurrent.TimeUnit.MILLISECONDS; + +import java.sql.Timestamp; +import java.time.Duration; +import java.time.Instant; +import java.util.Date; +import java.util.Iterator; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +/** + * A timestamp generated by {@link MonotonicClock#propose()}. + * <p> + * ProposedTimestamp implements AutoCloseable so that implementations can + * release resources associated with obtaining certainty about time elapsing. + * For example the constructing MonotonicClock may start network IO with peers + * when creating the ProposedTimestamp, and {@link #close()} can ensure those + * network resources are released in a timely fashion. + * + * @since 4.6 + */ +public abstract class ProposedTimestamp implements AutoCloseable { + /** + * Wait for several timestamps. + * + * @param times + * timestamps to wait on. + * @param maxWait + * how long to wait for the timestamps. + * @throws InterruptedException + * current thread was interrupted before the waiting process + * completed normally. + * @throws TimeoutException + * the timeout was reached without the proposed timestamp become + * certainly in the past. + */ + public static void blockUntil(Iterable<ProposedTimestamp> times, + Duration maxWait) throws TimeoutException, InterruptedException { + Iterator<ProposedTimestamp> itr = times.iterator(); + if (!itr.hasNext()) { + return; + } + + long now = System.currentTimeMillis(); + long deadline = now + maxWait.toMillis(); + for (;;) { + long w = deadline - now; + if (w < 0) { + throw new TimeoutException(); + } + itr.next().blockUntil(Duration.ofMillis(w)); + if (itr.hasNext()) { + now = System.currentTimeMillis(); + } else { + break; + } + } + } + + /** + * Read the timestamp as {@code unit} since the epoch. + * <p> + * The timestamp value for a specific {@code ProposedTimestamp} object never + * changes, and can be read before {@link #blockUntil(Duration)}. + * + * @param unit + * what unit to return the timestamp in. The timestamp will be + * rounded if the unit is bigger than the clock's granularity. + * @return {@code unit} since the epoch. + */ + public abstract long read(TimeUnit unit); + + /** + * Wait for this proposed timestamp to be certainly in the recent past. + * <p> + * This method forces the caller to wait up to {@code timeout} for + * {@code this} to pass sufficiently into the past such that the creating + * {@link MonotonicClock} instance will not create an earlier timestamp. + * + * @param maxWait + * how long the implementation may block the caller. + * @throws InterruptedException + * current thread was interrupted before the waiting process + * completed normally. + * @throws TimeoutException + * the timeout was reached without the proposed timestamp + * becoming certainly in the past. + */ + public abstract void blockUntil(Duration maxWait) + throws InterruptedException, TimeoutException; + + /** @return milliseconds since epoch; {@code read(MILLISECONDS}). */ + public long millis() { + return read(MILLISECONDS); + } + + /** @return microseconds since epoch; {@code read(MICROSECONDS}). */ + public long micros() { + return read(MICROSECONDS); + } + + /** @return time since epoch, with up to microsecond resolution. */ + public Instant instant() { + long usec = micros(); + long secs = usec / 1000000L; + long nanos = (usec % 1000000L) * 1000L; + return Instant.ofEpochSecond(secs, nanos); + } + + /** @return time since epoch, with up to microsecond resolution. */ + public Timestamp timestamp() { + return Timestamp.from(instant()); + } + + /** @return time since epoch, with up to millisecond resolution. */ + public Date date() { + return new Date(millis()); + } + + /** Release resources allocated by this timestamp. */ + @Override + public void close() { + // Do nothing by default. + } + + @Override + public String toString() { + return instant().toString(); + } +} @@ -51,7 +51,7 @@ <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit-parent</artifactId> <packaging>pom</packaging> - <version>4.5.3-SNAPSHOT</version> + <version>4.6.2-SNAPSHOT</version> <name>JGit - Parent</name> <url>${jgit-url}</url> @@ -190,25 +190,23 @@ <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <maven.build.timestamp.format>yyyyMMddHHmm</maven.build.timestamp.format> <bundle-manifest>${project.build.directory}/META-INF/MANIFEST.MF</bundle-manifest> - <!-- set JDK_HOME to JAVA_HOME path of JDK7 installation in order to compile against JDK 7 class library --> - <JDK_HOME>${JAVA_HOME}</JDK_HOME> <jgit-last-release-version>4.2.0.201601211800-r</jgit-last-release-version> <jsch-version>0.1.53</jsch-version> - <javaewah-version>0.7.9</javaewah-version> + <javaewah-version>1.1.6</javaewah-version> <junit-version>4.12</junit-version> <test-fork-count>1C</test-fork-count> <args4j-version>2.0.15</args4j-version> <commons-compress-version>1.6</commons-compress-version> <osgi-core-version>4.3.1</osgi-core-version> <servlet-api-version>3.1.0</servlet-api-version> - <jetty-version>9.2.13.v20150730</jetty-version> + <jetty-version>9.3.17.v20170317</jetty-version> <japicmp-version>0.5.3</japicmp-version> <httpclient-version>4.3.6</httpclient-version> <slf4j-version>1.7.2</slf4j-version> <log4j-version>1.2.15</log4j-version> - <maven-javadoc-plugin-version>2.10.3</maven-javadoc-plugin-version> - <tycho-extras-version>0.25.0</tycho-extras-version> + <maven-javadoc-plugin-version>2.10.4</maven-javadoc-plugin-version> + <tycho-extras-version>0.26.0</tycho-extras-version> <gson-version>2.2.4</gson-version> <!-- Properties to enable jacoco code coverage analysis --> @@ -241,7 +239,7 @@ <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> - <version>2.6</version> + <version>3.0.2</version> <configuration> <archive> <manifestEntries> @@ -260,15 +258,59 @@ <plugin> <artifactId>maven-compiler-plugin</artifactId> - <version>3.5.1</version> + <version>3.6.0</version> <configuration> <encoding>UTF-8</encoding> - <source>1.7</source> - <target>1.7</target> - <compilerArguments> - <bootclasspath>${JDK_HOME}${file.separator}jre${file.separator}lib${file.separator}rt.jar${path.separator}${JDK_HOME}${file.separator}jre${file.separator}lib${file.separator}jsse.jar${path.separator}${JDK_HOME}${file.separator}jre${file.separator}lib${file.separator}jce.jar</bootclasspath> - </compilerArguments> + <source>1.8</source> + <target>1.8</target> </configuration> + <executions> + <execution> + <id>default-compile</id> + <phase>compile</phase> + <goals> + <goal>compile</goal> + </goals> + <configuration> + <includes> + <include>org/eclipse/jgit/transport/InsecureCipherFactory.java</include> + </includes> + </configuration> + </execution> + <execution> + <id>compile-with-errorprone</id> + <phase>compile</phase> + <goals> + <goal>compile</goal> + </goals> + <configuration> + <compilerId>javac-with-errorprone</compilerId> + <forceJavacCompilerUse>true</forceJavacCompilerUse> + <excludes> + <exclude>org/eclipse/jgit/transport/InsecureCipherFactory.java</exclude> + </excludes> + </configuration> + </execution> + </executions> + <dependencies> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-compiler-javac</artifactId> + <version>2.8.1</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-compiler-javac-errorprone</artifactId> + <version>2.8.1</version> + </dependency> + <!-- override plexus-compiler-javac-errorprone's dependency on + Error Prone with the latest version --> + <dependency> + <groupId>com.google.errorprone</groupId> + <artifactId>error_prone_core</artifactId> + <version>2.0.15</version> + </dependency> + </dependencies> </plugin> <plugin> @@ -291,13 +333,13 @@ <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> - <version>2.10</version> + <version>3.0.0</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-source-plugin</artifactId> - <version>3.0.0</version> + <version>3.0.1</version> </plugin> <plugin> @@ -319,13 +361,13 @@ <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>build-helper-maven-plugin</artifactId> - <version>1.10</version> + <version>1.12</version> </plugin> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>findbugs-maven-plugin</artifactId> - <version>3.0.3</version> + <version>3.0.4</version> <configuration> <findbugsXmlOutput>true</findbugsXmlOutput> <failOnError>false</failOnError> @@ -342,11 +384,11 @@ <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-pmd-plugin</artifactId> - <version>3.6</version> + <version>3.7</version> <configuration> <sourceEncoding>utf-8</sourceEncoding> <minimumTokens>100</minimumTokens> - <targetJdk>1.7</targetJdk> + <targetJdk>1.8</targetJdk> <format>xml</format> <failOnViolation>false</failOnViolation> </configuration> @@ -377,12 +419,12 @@ <plugin> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven-plugin</artifactId> - <version>0.7.6.201602180812</version> + <version>0.7.8</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-site-plugin</artifactId> - <version>3.5.1</version> + <version>3.6</version> <dependencies> <dependency><!-- add support for ssh/scp --> <groupId>org.apache.maven.wagon</groupId> @@ -459,7 +501,7 @@ <quiet>true</quiet> <excludePackageNames>org.eclipse.jgit.http.test</excludePackageNames> <links> - <link>http://docs.oracle.com/javase/7/docs/api</link> + <link>http://docs.oracle.com/javase/8/docs/api</link> </links> </configuration> <executions> @@ -668,12 +710,6 @@ <profiles> <profile> - <id>jgit.java7</id> - <activation> - <jdk>[1.7,)</jdk> - </activation> - </profile> - <profile> <id>jgit.java8</id> <activation> <jdk>[1.8,)</jdk> diff --git a/tools/eclipse-JGit-Format.xml b/tools/eclipse-JGit-Format.xml index 278b449ff8..490758a56c 100644 --- a/tools/eclipse-JGit-Format.xml +++ b/tools/eclipse-JGit-Format.xml @@ -45,7 +45,7 @@ <setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_binary_operator" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="0"/> -<setting id="org.eclipse.jdt.core.compiler.source" value="1.7"/> +<setting id="org.eclipse.jdt.core.compiler.source" value="1.8"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="true"/> @@ -156,7 +156,7 @@ <setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference" value="do not insert"/> <setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression" value="16"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/> -<setting id="org.eclipse.jdt.core.compiler.compliance" value="1.7"/> +<setting id="org.eclipse.jdt.core.compiler.compliance" value="1.8"/> <setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/> @@ -227,7 +227,7 @@ <setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws" value="insert"/> <setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="16"/> <setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="insert"/> -<setting id="org.eclipse.jdt.core.compiler.codegen.targetPlatform" value="1.7"/> +<setting id="org.eclipse.jdt.core.compiler.codegen.targetPlatform" value="1.8"/> <setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/> <setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="false"/> <setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member" value="insert"/> |