diff options
169 files changed, 2810 insertions, 573 deletions
diff --git a/.buckversion b/.buckversion index 561a769f10..f5fe016979 100644 --- a/.buckversion +++ b/.buckversion @@ -1 +1 @@ -ca8d6cbac373a690f543c5159eec0116e76187a9 +e64a2e2ada022f81e42be750b774024469551398 diff --git a/.gitignore b/.gitignore index 6c62199484..95ad1744b5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ -/target +/.buckd /.project /buck-cache /buck-out +/target diff --git a/org.eclipse.jgit.ant.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.ant.test/META-INF/MANIFEST.MF index afa0f5c24b..371c66fb19 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.3.2.qualifier +Bundle-Version: 4.4.2.qualifier Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-1.7 Import-Package: org.apache.tools.ant, - org.eclipse.jgit.ant.tasks;version="[4.3.2,4.4.0)", - org.eclipse.jgit.internal.storage.file;version="[4.3.2,4.4.0)", - org.eclipse.jgit.junit;version="[4.3.2,4.4.0)", - org.eclipse.jgit.lib;version="[4.3.2,4.4.0)", - org.eclipse.jgit.util;version="[4.3.2,4.4.0)", + org.eclipse.jgit.ant.tasks;version="[4.4.2,4.5.0)", + org.eclipse.jgit.internal.storage.file;version="[4.4.2,4.5.0)", + org.eclipse.jgit.junit;version="[4.4.2,4.5.0)", + org.eclipse.jgit.lib;version="[4.4.2,4.5.0)", + org.eclipse.jgit.util;version="[4.4.2,4.5.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/pom.xml b/org.eclipse.jgit.ant.test/pom.xml index fc1257d644..a4f43553d2 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.3.2-SNAPSHOT</version> + <version>4.4.2-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.ant.test</artifactId> diff --git a/org.eclipse.jgit.ant/META-INF/MANIFEST.MF b/org.eclipse.jgit.ant/META-INF/MANIFEST.MF index 98da2c0525..4ae7d7b10b 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.3.2.qualifier +Bundle-Version: 4.4.2.qualifier Bundle-RequiredExecutionEnvironment: JavaSE-1.7 Import-Package: org.apache.tools.ant, - org.eclipse.jgit.storage.file;version="[4.3.2,4.4.0)" + org.eclipse.jgit.storage.file;version="[4.4.2,4.5.0)" Bundle-Localization: plugin Bundle-Vendor: %Provider-Name -Export-Package: org.eclipse.jgit.ant.tasks;version="4.3.2"; +Export-Package: org.eclipse.jgit.ant.tasks;version="4.4.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 6fc806f132..6f21e4d004 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.3.2-SNAPSHOT</version> + <version>4.4.2-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.ant</artifactId> @@ -72,7 +72,7 @@ <dependency> <groupId>org.apache.ant</groupId> <artifactId>ant</artifactId> - <version>1.9.2</version> + <version>1.9.6</version> </dependency> </dependencies> diff --git a/org.eclipse.jgit.archive/META-INF/MANIFEST.MF b/org.eclipse.jgit.archive/META-INF/MANIFEST.MF index a185d1f782..2b960aea94 100644 --- a/org.eclipse.jgit.archive/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.archive/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Bundle-SymbolicName: org.eclipse.jgit.archive -Bundle-Version: 4.3.2.qualifier +Bundle-Version: 4.4.2.qualifier Bundle-Vendor: %provider_name Bundle-Localization: plugin Bundle-RequiredExecutionEnvironment: JavaSE-1.7 @@ -12,14 +12,14 @@ Import-Package: org.apache.commons.compress.archivers;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.3.2,4.4.0)", - org.eclipse.jgit.lib;version="[4.3.2,4.4.0)", - org.eclipse.jgit.nls;version="[4.3.2,4.4.0)", - org.eclipse.jgit.util;version="[4.3.2,4.4.0)", + org.eclipse.jgit.api;version="[4.4.2,4.5.0)", + org.eclipse.jgit.lib;version="[4.4.2,4.5.0)", + org.eclipse.jgit.nls;version="[4.4.2,4.5.0)", + org.eclipse.jgit.util;version="[4.4.2,4.5.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.3.2"; +Export-Package: org.eclipse.jgit.archive;version="4.4.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 cf164a9c29..b4a519c419 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.3.2.qualifier -Eclipse-SourceBundle: org.eclipse.jgit.archive;version="4.3.2.qualifier";roots="." +Bundle-Version: 4.4.2.qualifier +Eclipse-SourceBundle: org.eclipse.jgit.archive;version="4.4.2.qualifier";roots="." diff --git a/org.eclipse.jgit.archive/pom.xml b/org.eclipse.jgit.archive/pom.xml index 7b9c6ac893..0df67f8d01 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.3.2-SNAPSHOT</version> + <version>4.4.2-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.archive</artifactId> diff --git a/org.eclipse.jgit.http.apache/META-INF/MANIFEST.MF b/org.eclipse.jgit.http.apache/META-INF/MANIFEST.MF index 0872d4983a..200e0cef57 100644 --- a/org.eclipse.jgit.http.apache/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.http.apache/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %Bundle-Name Bundle-SymbolicName: org.eclipse.jgit.http.apache -Bundle-Version: 4.3.2.qualifier +Bundle-Version: 4.4.2.qualifier Bundle-RequiredExecutionEnvironment: JavaSE-1.7 Bundle-Localization: plugin Bundle-Vendor: %Provider-Name @@ -19,10 +19,10 @@ Import-Package: org.apache.http;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.3.2,4.4.0)", - org.eclipse.jgit.transport.http;version="[4.3.2,4.4.0)", - org.eclipse.jgit.util;version="[4.3.2,4.4.0)" -Export-Package: org.eclipse.jgit.transport.http.apache;version="4.3.2"; + org.eclipse.jgit.nls;version="[4.4.2,4.5.0)", + org.eclipse.jgit.transport.http;version="[4.4.2,4.5.0)", + org.eclipse.jgit.util;version="[4.4.2,4.5.0)" +Export-Package: org.eclipse.jgit.transport.http.apache;version="4.4.2"; uses:="org.eclipse.jgit.transport.http, javax.net.ssl, org.apache.http.client, diff --git a/org.eclipse.jgit.http.apache/pom.xml b/org.eclipse.jgit.http.apache/pom.xml index 2b0b58d5f9..45bb22e8f1 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.3.2-SNAPSHOT</version> + <version>4.4.2-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.http.apache</artifactId> diff --git a/org.eclipse.jgit.http.server/META-INF/MANIFEST.MF b/org.eclipse.jgit.http.server/META-INF/MANIFEST.MF index 848b55e427..d28ac28e6f 100644 --- a/org.eclipse.jgit.http.server/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.http.server/META-INF/MANIFEST.MF @@ -2,13 +2,13 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Bundle-SymbolicName: org.eclipse.jgit.http.server -Bundle-Version: 4.3.2.qualifier +Bundle-Version: 4.4.2.qualifier Bundle-Localization: plugin Bundle-Vendor: %provider_name -Export-Package: org.eclipse.jgit.http.server;version="4.3.2", - org.eclipse.jgit.http.server.glue;version="4.3.2"; +Export-Package: org.eclipse.jgit.http.server;version="4.4.2", + org.eclipse.jgit.http.server.glue;version="4.4.2"; uses:="javax.servlet,javax.servlet.http", - org.eclipse.jgit.http.server.resolver;version="4.3.2"; + org.eclipse.jgit.http.server.resolver;version="4.4.2"; uses:="org.eclipse.jgit.transport.resolver, org.eclipse.jgit.lib, org.eclipse.jgit.transport, @@ -17,12 +17,12 @@ Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-1.7 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.3.2,4.4.0)", - org.eclipse.jgit.internal.storage.dfs;version="[4.3.2,4.4.0)", - org.eclipse.jgit.internal.storage.file;version="[4.3.2,4.4.0)", - org.eclipse.jgit.lib;version="[4.3.2,4.4.0)", - org.eclipse.jgit.nls;version="[4.3.2,4.4.0)", - org.eclipse.jgit.revwalk;version="[4.3.2,4.4.0)", - org.eclipse.jgit.transport;version="[4.3.2,4.4.0)", - org.eclipse.jgit.transport.resolver;version="[4.3.2,4.4.0)", - org.eclipse.jgit.util;version="[4.3.2,4.4.0)" + org.eclipse.jgit.errors;version="[4.4.2,4.5.0)", + org.eclipse.jgit.internal.storage.dfs;version="[4.4.2,4.5.0)", + org.eclipse.jgit.internal.storage.file;version="[4.4.2,4.5.0)", + org.eclipse.jgit.lib;version="[4.4.2,4.5.0)", + org.eclipse.jgit.nls;version="[4.4.2,4.5.0)", + org.eclipse.jgit.revwalk;version="[4.4.2,4.5.0)", + org.eclipse.jgit.transport;version="[4.4.2,4.5.0)", + org.eclipse.jgit.transport.resolver;version="[4.4.2,4.5.0)", + org.eclipse.jgit.util;version="[4.4.2,4.5.0)" diff --git a/org.eclipse.jgit.http.server/pom.xml b/org.eclipse.jgit.http.server/pom.xml index c6de937212..6c5db673b7 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.3.2-SNAPSHOT</version> + <version>4.4.2-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.http.server</artifactId> diff --git a/org.eclipse.jgit.http.test/.classpath b/org.eclipse.jgit.http.test/.classpath index 2fdcc94f18..e1a1a64a49 100644 --- a/org.eclipse.jgit.http.test/.classpath +++ b/org.eclipse.jgit.http.test/.classpath @@ -3,5 +3,6 @@ <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.pde.core.requiredPlugins"/> <classpathentry kind="src" path="tst"/> + <classpathentry kind="src" path="src"/> <classpathentry kind="output" path="bin"/> </classpath> diff --git a/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF index fefdb66db3..90ee5697c3 100644 --- a/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.http.test/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Bundle-SymbolicName: org.eclipse.jgit.http.test -Bundle-Version: 4.3.2.qualifier +Bundle-Version: 4.4.2.qualifier Bundle-Vendor: %provider_name Bundle-Localization: plugin Bundle-RequiredExecutionEnvironment: JavaSE-1.7 @@ -22,23 +22,24 @@ Import-Package: javax.servlet;version="[2.5.0,3.2.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.3.2,4.4.0)", - org.eclipse.jgit.http.server;version="[4.3.2,4.4.0)", - org.eclipse.jgit.http.server.glue;version="[4.3.2,4.4.0)", - org.eclipse.jgit.http.server.resolver;version="[4.3.2,4.4.0)", - org.eclipse.jgit.internal;version="[4.3.2,4.4.0)", - org.eclipse.jgit.internal.storage.file;version="[4.3.2,4.4.0)", - org.eclipse.jgit.junit;version="[4.3.2,4.4.0)", - org.eclipse.jgit.junit.http;version="[4.3.2,4.4.0)", - org.eclipse.jgit.lib;version="[4.3.2,4.4.0)", - org.eclipse.jgit.nls;version="[4.3.2,4.4.0)", - org.eclipse.jgit.revwalk;version="[4.3.2,4.4.0)", - org.eclipse.jgit.storage.file;version="[4.3.2,4.4.0)", - org.eclipse.jgit.transport;version="[4.3.2,4.4.0)", - org.eclipse.jgit.transport.http;version="[4.3.2,4.4.0)", - org.eclipse.jgit.transport.http.apache;version="[4.3.2,4.4.0)", - org.eclipse.jgit.transport.resolver;version="[4.3.2,4.4.0)", - org.eclipse.jgit.util;version="[4.3.2,4.4.0)", + org.eclipse.jgit.errors;version="[4.4.2,4.5.0)", + org.eclipse.jgit.http.server;version="[4.4.2,4.5.0)", + org.eclipse.jgit.http.server.glue;version="[4.4.2,4.5.0)", + org.eclipse.jgit.http.server.resolver;version="[4.4.2,4.5.0)", + org.eclipse.jgit.internal;version="[4.4.2,4.5.0)", + org.eclipse.jgit.internal.storage.dfs;version="[4.4.2,4.5.0)", + org.eclipse.jgit.internal.storage.file;version="[4.4.2,4.5.0)", + org.eclipse.jgit.junit;version="[4.4.2,4.5.0)", + org.eclipse.jgit.junit.http;version="[4.4.2,4.5.0)", + org.eclipse.jgit.lib;version="[4.4.2,4.5.0)", + org.eclipse.jgit.nls;version="[4.4.2,4.5.0)", + org.eclipse.jgit.revwalk;version="[4.4.2,4.5.0)", + org.eclipse.jgit.storage.file;version="[4.4.2,4.5.0)", + org.eclipse.jgit.transport;version="[4.4.2,4.5.0)", + org.eclipse.jgit.transport.http;version="[4.4.2,4.5.0)", + org.eclipse.jgit.transport.http.apache;version="[4.4.2,4.5.0)", + org.eclipse.jgit.transport.resolver;version="[4.4.2,4.5.0)", + org.eclipse.jgit.util;version="[4.4.2,4.5.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 8fc34f7417..c39817f4dd 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.3.2-SNAPSHOT</version> + <version>4.4.2-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.http.test</artifactId> @@ -72,7 +72,6 @@ <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit</artifactId> <version>${project.version}</version> - <scope>test</scope> </dependency> <dependency> @@ -111,6 +110,7 @@ </dependencies> <build> + <sourceDirectory>src/</sourceDirectory> <testSourceDirectory>tst/</testSourceDirectory> <testResources> diff --git a/org.eclipse.jgit.http.test/src/org/eclipse/jgit/http/test/RefsUnreadableInMemoryRepository.java b/org.eclipse.jgit.http.test/src/org/eclipse/jgit/http/test/RefsUnreadableInMemoryRepository.java new file mode 100644 index 0000000000..a1e41d12d5 --- /dev/null +++ b/org.eclipse.jgit.http.test/src/org/eclipse/jgit/http/test/RefsUnreadableInMemoryRepository.java @@ -0,0 +1,93 @@ +/* + * 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.http.test; + +import java.io.IOException; + +import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription; +import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository; +import org.eclipse.jgit.lib.RefDatabase; + +/** + * An {@link InMemoryRepository} whose refs can be made unreadable for testing + * purposes. + */ +class RefsUnreadableInMemoryRepository extends InMemoryRepository { + + private final RefsUnreadableRefDatabase refs; + + private volatile boolean failing; + + RefsUnreadableInMemoryRepository(DfsRepositoryDescription repoDesc) { + super(repoDesc); + refs = new RefsUnreadableRefDatabase(); + failing = false; + } + + @Override + public RefDatabase getRefDatabase() { + return refs; + } + + /** + * Make the ref database unable to scan its refs. + * <p> + * It may be useful to follow a call to startFailing with a call to + * {@link RefDatabase#refresh()}, ensuring the next ref read fails. + */ + void startFailing() { + failing = true; + } + + private class RefsUnreadableRefDatabase extends MemRefDatabase { + + @Override + protected RefCache scanAllRefs() throws IOException { + if (failing) { + throw new IOException("disk failed, no refs found"); + } else { + return super.scanAllRefs(); + } + } + } +} 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 0f3d3c6cf5..073c751286 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 @@ -82,9 +82,11 @@ import org.eclipse.jgit.errors.RepositoryNotFoundException; import org.eclipse.jgit.errors.TransportException; import org.eclipse.jgit.http.server.GitServlet; import org.eclipse.jgit.internal.JGitText; +import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription; import org.eclipse.jgit.junit.TestRepository; import org.eclipse.jgit.junit.TestRng; import org.eclipse.jgit.junit.http.AccessEvent; +import org.eclipse.jgit.junit.http.AppServer; import org.eclipse.jgit.junit.http.HttpTestCase; import org.eclipse.jgit.lib.ConfigConstants; import org.eclipse.jgit.lib.Constants; @@ -155,18 +157,7 @@ public class SmartClientSmartServerTest extends HttpTestCase { ServletContextHandler app = server.addContext("/git"); GitServlet gs = new GitServlet(); - gs.setRepositoryResolver(new RepositoryResolver<HttpServletRequest>() { - public Repository open(HttpServletRequest req, String name) - throws RepositoryNotFoundException, - ServiceNotEnabledException { - if (!name.equals(srcName)) - throw new RepositoryNotFoundException(name); - - final Repository db = src.getRepository(); - db.incrementOpen(); - return db; - } - }); + gs.setRepositoryResolver(new TestRepoResolver(src, srcName)); app.addServlet(new ServletHolder(gs), "/*"); ServletContextHandler broken = server.addContext("/bad"); @@ -509,6 +500,51 @@ public class SmartClientSmartServerTest extends HttpTestCase { } @Test + public void testFetch_RefsUnreadableOnUpload() throws Exception { + AppServer noRefServer = new AppServer(); + try { + final String repoName = "refs-unreadable"; + RefsUnreadableInMemoryRepository badRefsRepo = new RefsUnreadableInMemoryRepository( + new DfsRepositoryDescription(repoName)); + final TestRepository<Repository> repo = new TestRepository<Repository>( + badRefsRepo); + + ServletContextHandler app = noRefServer.addContext("/git"); + GitServlet gs = new GitServlet(); + gs.setRepositoryResolver(new TestRepoResolver(repo, repoName)); + app.addServlet(new ServletHolder(gs), "/*"); + noRefServer.setUp(); + + RevBlob A2_txt = repo.blob("A2"); + RevCommit A2 = repo.commit().add("A2_txt", A2_txt).create(); + RevCommit B2 = repo.commit().parent(A2).add("A2_txt", "C2") + .add("B2", "B2").create(); + repo.update(master, B2); + + URIish badRefsURI = new URIish(noRefServer.getURI() + .resolve(app.getContextPath() + "/" + repoName).toString()); + + Repository dst = createBareRepository(); + try (Transport t = Transport.open(dst, badRefsURI); + FetchConnection c = t.openFetch()) { + // We start failing here to exercise the post-advertisement + // upload pack handler. + badRefsRepo.startFailing(); + // Need to flush caches because ref advertisement populated them. + badRefsRepo.getRefDatabase().refresh(); + c.fetch(NullProgressMonitor.INSTANCE, + Collections.singleton(c.getRef(master)), + Collections.<ObjectId> emptySet()); + fail("Successfully served ref with value " + c.getRef(master)); + } catch (TransportException err) { + assertEquals("internal server error", err.getMessage()); + } + } finally { + noRefServer.tearDown(); + } + } + + @Test public void testPush_NotAuthorized() throws Exception { final TestRepository src = createTestRepository(); final RevBlob Q_txt = src.blob("new text"); @@ -677,4 +713,28 @@ public class SmartClientSmartServerTest extends HttpTestCase { cfg.setBoolean("http", null, "receivepack", true); cfg.save(); } + + private final class TestRepoResolver + implements RepositoryResolver<HttpServletRequest> { + + private final TestRepository<Repository> repo; + + private final String repoName; + + private TestRepoResolver(TestRepository<Repository> repo, + String repoName) { + this.repo = repo; + this.repoName = repoName; + } + + public Repository open(HttpServletRequest req, String name) + throws RepositoryNotFoundException, ServiceNotEnabledException { + if (!name.equals(repoName)) + throw new RepositoryNotFoundException(name); + + Repository db = repo.getRepository(); + db.incrementOpen(); + return db; + } + } } diff --git a/org.eclipse.jgit.junit.http/META-INF/MANIFEST.MF b/org.eclipse.jgit.junit.http/META-INF/MANIFEST.MF index bd26ac098d..c406a14bb2 100644 --- a/org.eclipse.jgit.junit.http/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.junit.http/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Bundle-SymbolicName: org.eclipse.jgit.junit.http -Bundle-Version: 4.3.2.qualifier +Bundle-Version: 4.4.2.qualifier Bundle-Localization: plugin Bundle-Vendor: %provider_name Bundle-ActivationPolicy: lazy @@ -20,16 +20,16 @@ Import-Package: javax.servlet;version="[2.5.0,3.2.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.3.2,4.4.0)", - org.eclipse.jgit.http.server;version="[4.3.2,4.4.0)", - org.eclipse.jgit.internal.storage.file;version="[4.3.2,4.4.0)", - org.eclipse.jgit.junit;version="[4.3.2,4.4.0)", - org.eclipse.jgit.lib;version="[4.3.2,4.4.0)", - org.eclipse.jgit.revwalk;version="[4.3.2,4.4.0)", - org.eclipse.jgit.transport;version="[4.3.2,4.4.0)", - org.eclipse.jgit.transport.resolver;version="[4.3.2,4.4.0)", + org.eclipse.jgit.errors;version="[4.4.2,4.5.0)", + org.eclipse.jgit.http.server;version="[4.4.2,4.5.0)", + org.eclipse.jgit.internal.storage.file;version="[4.4.2,4.5.0)", + org.eclipse.jgit.junit;version="[4.4.2,4.5.0)", + org.eclipse.jgit.lib;version="[4.4.2,4.5.0)", + org.eclipse.jgit.revwalk;version="[4.4.2,4.5.0)", + org.eclipse.jgit.transport;version="[4.4.2,4.5.0)", + org.eclipse.jgit.transport.resolver;version="[4.4.2,4.5.0)", org.junit;version="[4.0.0,5.0.0)" -Export-Package: org.eclipse.jgit.junit.http;version="4.3.2"; +Export-Package: org.eclipse.jgit.junit.http;version="4.4.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 43fdb8ac07..201998f144 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.3.2-SNAPSHOT</version> + <version>4.4.2-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.junit.http</artifactId> diff --git a/org.eclipse.jgit.junit/META-INF/MANIFEST.MF b/org.eclipse.jgit.junit/META-INF/MANIFEST.MF index 89171bcc8a..0202328c70 100644 --- a/org.eclipse.jgit.junit/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.junit/META-INF/MANIFEST.MF @@ -2,27 +2,27 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Bundle-SymbolicName: org.eclipse.jgit.junit -Bundle-Version: 4.3.2.qualifier +Bundle-Version: 4.4.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.3.2,4.4.0)", - org.eclipse.jgit.api.errors;version="[4.3.2,4.4.0)", - org.eclipse.jgit.dircache;version="[4.3.2,4.4.0)", - org.eclipse.jgit.errors;version="[4.3.2,4.4.0)", - org.eclipse.jgit.internal.storage.file;version="[4.3.2,4.4.0)", - org.eclipse.jgit.internal.storage.pack;version="[4.3.2,4.4.0)", - org.eclipse.jgit.lib;version="[4.3.2,4.4.0)", - org.eclipse.jgit.merge;version="[4.3.2,4.4.0)", - org.eclipse.jgit.revwalk;version="[4.3.2,4.4.0)", - org.eclipse.jgit.storage.file;version="[4.3.2,4.4.0)", - org.eclipse.jgit.treewalk;version="[4.3.2,4.4.0)", - org.eclipse.jgit.treewalk.filter;version="[4.3.2,4.4.0)", - org.eclipse.jgit.util;version="[4.3.2,4.4.0)", - org.eclipse.jgit.util.io;version="[4.3.2,4.4.0)", +Import-Package: org.eclipse.jgit.api;version="[4.4.2,4.5.0)", + org.eclipse.jgit.api.errors;version="[4.4.2,4.5.0)", + org.eclipse.jgit.dircache;version="[4.4.2,4.5.0)", + org.eclipse.jgit.errors;version="[4.4.2,4.5.0)", + org.eclipse.jgit.internal.storage.file;version="[4.4.2,4.5.0)", + org.eclipse.jgit.internal.storage.pack;version="[4.4.2,4.5.0)", + org.eclipse.jgit.lib;version="[4.4.2,4.5.0)", + org.eclipse.jgit.merge;version="[4.4.2,4.5.0)", + org.eclipse.jgit.revwalk;version="[4.4.2,4.5.0)", + org.eclipse.jgit.storage.file;version="[4.4.2,4.5.0)", + org.eclipse.jgit.treewalk;version="[4.4.2,4.5.0)", + org.eclipse.jgit.treewalk.filter;version="[4.4.2,4.5.0)", + org.eclipse.jgit.util;version="[4.4.2,4.5.0)", + org.eclipse.jgit.util.io;version="[4.4.2,4.5.0)", org.junit;version="[4.0.0,5.0.0)" -Export-Package: org.eclipse.jgit.junit;version="4.3.2"; +Export-Package: org.eclipse.jgit.junit;version="4.4.2"; uses:="org.eclipse.jgit.dircache, org.eclipse.jgit.lib, org.eclipse.jgit.revwalk, diff --git a/org.eclipse.jgit.junit/pom.xml b/org.eclipse.jgit.junit/pom.xml index bb2b6771b5..90dd86519d 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.3.2-SNAPSHOT</version> + <version>4.4.2-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.junit</artifactId> diff --git a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/RepositoryTestCase.java b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/RepositoryTestCase.java index 86b87b4075..c282df03bd 100644 --- a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/RepositoryTestCase.java +++ b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/RepositoryTestCase.java @@ -406,7 +406,7 @@ public abstract class RepositoryTestCase extends LocalDiskRepositoryTestCase { String originalBranch = repo.getFullBranch(); boolean empty = repo.resolve(Constants.HEAD) == null; if (!empty) { - if (repo.getRef(branch) == null) + if (repo.findRef(branch) == null) git.branchCreate().setName(branch).call(); git.checkout().setName(branch).call(); } 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 1119e63824..0a2345f088 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 @@ -211,17 +211,6 @@ public class TestRepository<R extends Repository> { return new Date(mockSystemReader.getCurrentTime()); } - /** - * @return current date. - * - * @deprecated Use {@link #getDate()} instead. - */ - @Deprecated - public Date getClock() { - // Remove once Gitiles and Gerrit are using the updated JGit. - return getDate(); - } - /** @return timezone used for default identities. */ public TimeZone getTimeZone() { return mockSystemReader.getTimeZone(); @@ -501,7 +490,7 @@ public class TestRepository<R extends Repository> { */ public CommitBuilder amendRef(String ref) throws Exception { String name = normalizeRef(ref); - Ref r = db.getRef(name); + Ref r = db.exactRef(name); if (r == null) throw new IOException("Not a ref: " + ref); return amend(pool.parseCommit(r.getObjectId()), branch(name).commit()); @@ -586,6 +575,31 @@ public class TestRepository<R extends Repository> { } } + /** + * Delete a reference. + * + * @param ref + * the name of the reference to delete. This is normalized + * in the same way as {@link #update(String, AnyObjectId)}. + * @throws Exception + * @since 4.4 + */ + public void delete(String ref) throws Exception { + ref = normalizeRef(ref); + RefUpdate u = db.updateRef(ref); + switch (u.delete()) { + case FAST_FORWARD: + case FORCED: + case NEW: + case NO_CHANGE: + updateServerInfo(); + return; + + default: + throw new IOException("Cannot delete " + ref + " " + u.getResult()); + } + } + private static String normalizeRef(String ref) { if (Constants.HEAD.equals(ref)) { // nothing @@ -678,7 +692,7 @@ public class TestRepository<R extends Repository> { RevCommit parent = commit.getParent(0); pool.parseHeaders(parent); - Ref headRef = db.getRef(Constants.HEAD); + Ref headRef = db.exactRef(Constants.HEAD); if (headRef == null) throw new IOException("Missing HEAD"); RevCommit head = pool.parseCommit(headRef.getObjectId()); @@ -959,6 +973,15 @@ public class TestRepository<R extends Repository> { public RevCommit update(RevCommit to) throws Exception { return TestRepository.this.update(ref, to); } + + /** + * Delete this branch. + * @throws Exception + * @since 4.4 + */ + public void delete() throws Exception { + TestRepository.this.delete(ref); + } } /** Helper to generate a commit. */ @@ -991,7 +1014,7 @@ public class TestRepository<R extends Repository> { CommitBuilder(BranchBuilder b) throws Exception { branch = b; - Ref ref = db.getRef(branch.ref); + Ref ref = db.exactRef(branch.ref); if (ref != null && ref.getObjectId() != null) parent(pool.parseCommit(ref.getObjectId())); } 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 53d74cfdbe..7ef63d8711 100644 --- a/org.eclipse.jgit.lfs.server.test/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.lfs.server.test/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Bundle-SymbolicName: org.eclipse.jgit.lfs.server.test -Bundle-Version: 4.3.2.qualifier +Bundle-Version: 4.4.2.qualifier Bundle-Vendor: %provider_name Bundle-Localization: plugin Bundle-RequiredExecutionEnvironment: JavaSE-1.7 @@ -27,11 +27,11 @@ Import-Package: javax.servlet;version="[3.1.0,4.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.3.2,4.4.0)", - org.eclipse.jgit.lfs.lib;version="[4.3.2,4.4.0)", - org.eclipse.jgit.lfs.server.fs;version="[4.3.2,4.4.0)", - org.eclipse.jgit.lfs.test;version="[4.3.2,4.4.0)", - org.eclipse.jgit.util;version="[4.3.2,4.4.0)", + org.eclipse.jgit.junit.http;version="[4.4.2,4.5.0)", + org.eclipse.jgit.lfs.lib;version="[4.4.2,4.5.0)", + org.eclipse.jgit.lfs.server.fs;version="[4.4.2,4.5.0)", + org.eclipse.jgit.lfs.test;version="[4.4.2,4.5.0)", + org.eclipse.jgit.util;version="[4.4.2,4.5.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 05ee6f2eff..bf975c0624 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.3.2-SNAPSHOT</version> + <version>4.4.2-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.lfs.server.test</artifactId> diff --git a/org.eclipse.jgit.lfs.server/META-INF/MANIFEST.MF b/org.eclipse.jgit.lfs.server/META-INF/MANIFEST.MF index d15690056a..5688ea1b19 100644 --- a/org.eclipse.jgit.lfs.server/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.lfs.server/META-INF/MANIFEST.MF @@ -2,19 +2,19 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Bundle-SymbolicName: org.eclipse.jgit.lfs.server -Bundle-Version: 4.3.2.qualifier +Bundle-Version: 4.4.2.qualifier Bundle-Localization: plugin Bundle-Vendor: %provider_name -Export-Package: org.eclipse.jgit.lfs.server;version="4.3.2"; +Export-Package: org.eclipse.jgit.lfs.server;version="4.4.2"; uses:="javax.servlet.http, org.eclipse.jgit.lfs.lib", - org.eclipse.jgit.lfs.server.fs;version="4.3.2"; + org.eclipse.jgit.lfs.server.fs;version="4.4.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.3.2";x-internal:=true, - org.eclipse.jgit.lfs.server.s3;version="4.3.2"; + org.eclipse.jgit.lfs.server.internal;version="4.4.2";x-internal:=true, + org.eclipse.jgit.lfs.server.s3;version="4.4.2"; uses:="org.eclipse.jgit.lfs.server, org.eclipse.jgit.lfs.lib" Bundle-RequiredExecutionEnvironment: JavaSE-1.7 @@ -24,12 +24,12 @@ Import-Package: com.google.gson;version="[2.2.4,3.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.3.2,4.4.0)", - org.eclipse.jgit.internal;version="[4.3.2,4.4.0)", - org.eclipse.jgit.internal.storage.file;version="[4.3.2,4.4.0)", - org.eclipse.jgit.lfs.errors;version="[4.3.2,4.4.0)", - org.eclipse.jgit.lfs.lib;version="[4.3.2,4.4.0)", - org.eclipse.jgit.nls;version="[4.3.2,4.4.0)", - org.eclipse.jgit.transport.http;version="[4.3.2,4.4.0)", - org.eclipse.jgit.transport.http.apache;version="[4.3.2,4.4.0)", - org.eclipse.jgit.util;version="[4.3.2,4.4.0)" + org.eclipse.jgit.annotations;version="[4.4.2,4.5.0)", + org.eclipse.jgit.internal;version="[4.4.2,4.5.0)", + org.eclipse.jgit.internal.storage.file;version="[4.4.2,4.5.0)", + org.eclipse.jgit.lfs.errors;version="[4.4.2,4.5.0)", + org.eclipse.jgit.lfs.lib;version="[4.4.2,4.5.0)", + org.eclipse.jgit.nls;version="[4.4.2,4.5.0)", + org.eclipse.jgit.transport.http;version="[4.4.2,4.5.0)", + org.eclipse.jgit.transport.http.apache;version="[4.4.2,4.5.0)", + org.eclipse.jgit.util;version="[4.4.2,4.5.0)" diff --git a/org.eclipse.jgit.lfs.server/pom.xml b/org.eclipse.jgit.lfs.server/pom.xml index 0a81e33c88..71b05ea9ce 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.3.2-SNAPSHOT</version> + <version>4.4.2-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.lfs.server</artifactId> diff --git a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/FileLfsRepository.java b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/fs/FileLfsRepository.java index 2e71c0407e..dd70a364e4 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 @@ -147,7 +147,10 @@ public class FileLfsRepository implements LargeFileRepository { AtomicObjectOutputStream getOutputStream(AnyLongObjectId id) throws IOException { Path path = getPath(id); - Files.createDirectories(path.getParent()); + Path parent = path.getParent(); + if (parent != null) { + Files.createDirectories(parent); + } return new AtomicObjectOutputStream(path, id); } diff --git a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/s3/SignerV4.java b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/s3/SignerV4.java index 08bb4b96fd..f95b605c85 100644 --- a/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/s3/SignerV4.java +++ b/org.eclipse.jgit.lfs.server/src/org/eclipse/jgit/lfs/server/s3/SignerV4.java @@ -229,12 +229,12 @@ class SignerV4 { private static void addHostHeader(URL url, Map<String, String> headers) { - String hostHeader = url.getHost(); + StringBuilder hostHeader = new StringBuilder(url.getHost()); int port = url.getPort(); if (port > -1) { - hostHeader.concat(":" + Integer.toString(port)); //$NON-NLS-1$ + hostHeader.append(":").append(port); //$NON-NLS-1$ } - headers.put("Host", hostHeader); //$NON-NLS-1$ + headers.put("Host", hostHeader.toString()); //$NON-NLS-1$ } private static String canonicalizeHeaderNames( diff --git a/org.eclipse.jgit.lfs.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.lfs.test/META-INF/MANIFEST.MF index 173b0eb998..f0ecdef4ab 100644 --- a/org.eclipse.jgit.lfs.test/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.lfs.test/META-INF/MANIFEST.MF @@ -2,18 +2,18 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Bundle-SymbolicName: org.eclipse.jgit.lfs.test -Bundle-Version: 4.3.2.qualifier +Bundle-Version: 4.4.2.qualifier Bundle-Vendor: %provider_name Bundle-Localization: plugin Bundle-RequiredExecutionEnvironment: JavaSE-1.7 -Import-Package: org.eclipse.jgit.junit;version="[4.3.2,4.4.0)", - org.eclipse.jgit.lfs.errors;version="[4.3.2,4.4.0)", - org.eclipse.jgit.lfs.lib;version="[4.3.2,4.4.0)", - org.eclipse.jgit.lib;version="[4.3.2,4.4.0)", - org.eclipse.jgit.util;version="[4.3.2,4.4.0)", +Import-Package: org.eclipse.jgit.junit;version="[4.4.2,4.5.0)", + org.eclipse.jgit.lfs.errors;version="[4.4.2,4.5.0)", + org.eclipse.jgit.lfs.lib;version="[4.4.2,4.5.0)", + org.eclipse.jgit.lib;version="[4.4.2,4.5.0)", + org.eclipse.jgit.util;version="[4.4.2,4.5.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.3.2";x-friends:="org.eclipse.jgit.lfs.server.test" +Export-Package: org.eclipse.jgit.lfs.test;version="4.4.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 8e5d28b5d8..782c63e3f8 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.3.2-SNAPSHOT</version> + <version>4.4.2-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.lfs.test</artifactId> diff --git a/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF b/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF index 30baf05fac..77b6fcec97 100644 --- a/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.lfs/META-INF/MANIFEST.MF @@ -2,14 +2,14 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Bundle-SymbolicName: org.eclipse.jgit.lfs -Bundle-Version: 4.3.2.qualifier +Bundle-Version: 4.4.2.qualifier Bundle-Localization: plugin Bundle-Vendor: %provider_name -Export-Package: org.eclipse.jgit.lfs.errors;version="4.3.2", - org.eclipse.jgit.lfs.internal;version="4.3.2";x-friends:="org.eclipse.jgit.lfs.test", - org.eclipse.jgit.lfs.lib;version="4.3.2" +Export-Package: org.eclipse.jgit.lfs.errors;version="4.4.2", + org.eclipse.jgit.lfs.internal;version="4.4.2";x-friends:="org.eclipse.jgit.lfs.test", + org.eclipse.jgit.lfs.lib;version="4.4.2" Bundle-RequiredExecutionEnvironment: JavaSE-1.7 -Import-Package: org.eclipse.jgit.internal.storage.file;version="[4.3.2,4.4.0)", - org.eclipse.jgit.lib;version="[4.3.2,4.4.0)", - org.eclipse.jgit.nls;version="[4.3.2,4.4.0)", - org.eclipse.jgit.util;version="[4.3.2,4.4.0)" +Import-Package: org.eclipse.jgit.internal.storage.file;version="[4.4.2,4.5.0)", + org.eclipse.jgit.lib;version="[4.4.2,4.5.0)", + org.eclipse.jgit.nls;version="[4.4.2,4.5.0)", + org.eclipse.jgit.util;version="[4.4.2,4.5.0)" diff --git a/org.eclipse.jgit.lfs/pom.xml b/org.eclipse.jgit.lfs/pom.xml index b0f543d9b1..1e6fd7d60d 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.3.2-SNAPSHOT</version> + <version>4.4.2-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.lfs</artifactId> 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 3d13c7139e..5af0b637a2 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.3.2.qualifier" + version="4.4.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 81a8c3b455..c91a46d552 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.3.2-SNAPSHOT</version> + <version>4.4.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 f2597a46cc..f94dce8716 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.3.2.qualifier" + version="4.4.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 ca0fdca5bf..4f1cc80a38 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.3.2-SNAPSHOT</version> + <version>4.4.2-SNAPSHOT</version> </parent> <groupId>org.eclipse.jgit.feature</groupId> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.junit.feature/feature.xml index 829ef0a506..0014f6046a 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.3.2.qualifier" + version="4.4.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 6b900d433c..a4c763b6a4 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.3.2-SNAPSHOT</version> + <version>4.4.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 829c05623a..4f0ada2c7c 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.3.2.qualifier" + version="4.4.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 bf96616a5f..154df158f8 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.3.2-SNAPSHOT</version> + <version>4.4.2-SNAPSHOT</version> </parent> <groupId>org.eclipse.jgit.feature</groupId> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.feature/feature.xml index 73a9a13823..a6ae6d391e 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.3.2.qualifier" + version="4.4.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.3.0" match="equivalent"/> - <import feature="org.eclipse.jgit.lfs" version="4.3.0" match="equivalent"/> + <import feature="org.eclipse.jgit" version="4.4.1" match="equivalent"/> + <import feature="org.eclipse.jgit.lfs" version="4.4.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 262872166b..2013fc4fc0 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.3.2-SNAPSHOT</version> + <version>4.4.2-SNAPSHOT</version> </parent> <groupId>org.eclipse.jgit.feature</groupId> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/feature.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.pgm.source.feature/feature.xml index 4cb5cb7b3b..cc5223334d 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.3.2.qualifier" + version="4.4.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 c5015c6b6c..a29587331f 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.3.2-SNAPSHOT</version> + <version>4.4.2-SNAPSHOT</version> </parent> <groupId>org.eclipse.jgit.feature</groupId> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/pom.xml b/org.eclipse.jgit.packaging/org.eclipse.jgit.repository/pom.xml index 1410d68e88..43e15e532a 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.3.2-SNAPSHOT</version> + <version>4.4.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 4d49aae0a0..4f99110d36 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.3.2.qualifier" + version="4.4.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 204026b63d..f7372512a8 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.3.2-SNAPSHOT</version> + <version>4.4.2-SNAPSHOT</version> </parent> <groupId>org.eclipse.jgit.feature</groupId> diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/META-INF/MANIFEST.MF b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/META-INF/MANIFEST.MF index 4e1f66f7ae..a4ba267a0d 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.3.2.qualifier +Bundle-Version: 4.4.2.qualifier 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 e506aec37d..f7d5622552 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.target +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/jgit-4.6.target @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <?pde?> <!-- generated with https://github.com/mbarbero/fr.obeo.releng.targetplatform --> -<target name="jgit-4.5" sequenceNumber="1455835295"> +<target name="jgit-4.6" sequenceNumber="1463612069"> <locations> <location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit"> <unit id="org.eclipse.jetty.client" version="9.2.13.v20150730"/> @@ -23,8 +23,8 @@ <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.4.v201504302020"/> - <unit id="org.apache.ant.source" version="1.9.4.v201504302020"/> + <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"/> @@ -39,8 +39,8 @@ <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="javaewah" version="0.7.9.v201605172130"/> + <unit id="javaewah.source" version="0.7.9.v201605172130"/> <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"/> @@ -48,8 +48,8 @@ <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="org.junit" version="4.11.0.v201303080030"/> - <unit id="org.junit.source" version="4.11.0.v201303080030"/> + <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"/> @@ -58,11 +58,11 @@ <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/S20151204220443/repository/"/> + <repository location="http://download.eclipse.org/tools/orbit/downloads/drops/S20160518051658/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/"/> + <repository location="http://download.eclipse.org/releases/neon/"/> </location> </locations> </target> 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 3963361f6c..c784c1fb0e 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,8 +1,8 @@ -target "jgit-4.5" with source configurePhase +target "jgit-4.6" with source configurePhase include "projects/jetty-9.2.13.tpd" -include "orbit/S20151204220443-Neon.tpd" +include "orbit/R20160520211859-Neon.tpd" -location "http://download.eclipse.org/releases/mars/" { +location "http://download.eclipse.org/releases/neon/" { org.eclipse.osgi lazy }
\ No newline at end of file diff --git a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/S20151204220443-Neon.tpd b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20160520211859-Neon.tpd index 3afdbaa3d3..5aca0b7d7f 100644 --- a/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/S20151204220443-Neon.tpd +++ b/org.eclipse.jgit.packaging/org.eclipse.jgit.target/orbit/R20160520211859-Neon.tpd @@ -1,9 +1,9 @@ -target "S20151204220443-Neon" with source configurePhase +target "R20160520211859-Neon" with source configurePhase // see http://download.eclipse.org/tools/orbit/downloads/ -location "http://download.eclipse.org/tools/orbit/downloads/drops/S20151204220443/repository/" { - org.apache.ant [1.9.4.v201504302020,1.9.4.v201504302020] - org.apache.ant.source [1.9.4.v201504302020,1.9.4.v201504302020] +location "http://download.eclipse.org/tools/orbit/downloads/drops/R20160520211859/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] @@ -18,8 +18,8 @@ location "http://download.eclipse.org/tools/orbit/downloads/drops/S2015120422044 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] - javaewah [0.7.9.v201401101600,0.7.9.v201401101600] - javaewah.source [0.7.9.v201401101600,0.7.9.v201401101600] + javaewah [0.7.9.v201605172130,0.7.9.v201605172130] + javaewah.source [0.7.9.v201605172130,0.7.9.v201605172130] 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] @@ -27,8 +27,8 @@ location "http://download.eclipse.org/tools/orbit/downloads/drops/S2015120422044 com.google.gson [2.2.4.v201311231704,2.2.4.v201311231704] com.jcraft.jsch [0.1.53.v201508180515,0.1.53.v201508180515] com.jcraft.jsch.source [0.1.53.v201508180515,0.1.53.v201508180515] - org.junit [4.11.0.v201303080030,4.11.0.v201303080030] - org.junit.source [4.11.0.v201303080030,4.11.0.v201303080030] + 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] 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 4696b82719..cd6b4a391e 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.3.2-SNAPSHOT</version> + <version>4.4.2-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.target</artifactId> diff --git a/org.eclipse.jgit.packaging/pom.xml b/org.eclipse.jgit.packaging/pom.xml index 39b4be9043..71b859de53 100644 --- a/org.eclipse.jgit.packaging/pom.xml +++ b/org.eclipse.jgit.packaging/pom.xml @@ -53,15 +53,15 @@ <groupId>org.eclipse.jgit</groupId> <artifactId>jgit.tycho.parent</artifactId> - <version>4.3.2-SNAPSHOT</version> + <version>4.4.2-SNAPSHOT</version> <packaging>pom</packaging> <name>JGit Tycho Parent</name> <properties> - <tycho-version>0.23.0</tycho-version> + <tycho-version>0.25.0</tycho-version> <tycho-extras-version>${tycho-version}</tycho-extras-version> - <target-platform>jgit-4.5</target-platform> + <target-platform>jgit-4.6</target-platform> </properties> <pluginRepositories> @@ -149,7 +149,7 @@ <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> - <version>2.5</version> + <version>2.7</version> <configuration> <encoding>ISO-8859-1</encoding> </configuration> @@ -216,12 +216,12 @@ <plugin> <groupId>org.eclipse.cbi.maven.plugins</groupId> <artifactId>eclipse-jarsigner-plugin</artifactId> - <version>1.1.2</version> + <version>1.1.3</version> </plugin> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>build-helper-maven-plugin</artifactId> - <version>1.9</version> + <version>1.10</version> </plugin> </plugins> </pluginManagement> diff --git a/org.eclipse.jgit.pgm.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.pgm.test/META-INF/MANIFEST.MF index 097319d8c8..66d010c382 100644 --- a/org.eclipse.jgit.pgm.test/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.pgm.test/META-INF/MANIFEST.MF @@ -2,29 +2,30 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Bundle-SymbolicName: org.eclipse.jgit.pgm.test -Bundle-Version: 4.3.2.qualifier +Bundle-Version: 4.4.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.3.2,4.4.0)", - org.eclipse.jgit.api.errors;version="[4.3.2,4.4.0)", - org.eclipse.jgit.diff;version="[4.3.2,4.4.0)", - org.eclipse.jgit.dircache;version="[4.3.2,4.4.0)", - org.eclipse.jgit.internal.storage.file;version="4.3.2", - org.eclipse.jgit.junit;version="[4.3.2,4.4.0)", - org.eclipse.jgit.lib;version="[4.3.2,4.4.0)", - org.eclipse.jgit.merge;version="[4.3.2,4.4.0)", - org.eclipse.jgit.pgm;version="[4.3.2,4.4.0)", - org.eclipse.jgit.pgm.internal;version="[4.3.2,4.4.0)", - org.eclipse.jgit.pgm.opt;version="[4.3.2,4.4.0)", - org.eclipse.jgit.revwalk;version="[4.3.2,4.4.0)", - org.eclipse.jgit.storage.file;version="[4.3.2,4.4.0)", - org.eclipse.jgit.transport;version="[4.3.2,4.4.0)", - org.eclipse.jgit.treewalk;version="[4.3.2,4.4.0)", - org.eclipse.jgit.util;version="[4.3.2,4.4.0)", - org.eclipse.jgit.util.io;version="[4.3.2,4.4.0)", +Import-Package: org.eclipse.jgit.api;version="[4.4.2,4.5.0)", + org.eclipse.jgit.api.errors;version="[4.4.2,4.5.0)", + org.eclipse.jgit.diff;version="[4.4.2,4.5.0)", + org.eclipse.jgit.dircache;version="[4.4.2,4.5.0)", + org.eclipse.jgit.internal.storage.file;version="4.4.2", + org.eclipse.jgit.junit;version="[4.4.2,4.5.0)", + org.eclipse.jgit.lib;version="[4.4.2,4.5.0)", + org.eclipse.jgit.merge;version="[4.4.2,4.5.0)", + org.eclipse.jgit.pgm;version="[4.4.2,4.5.0)", + org.eclipse.jgit.pgm.internal;version="[4.4.2,4.5.0)", + org.eclipse.jgit.pgm.opt;version="[4.4.2,4.5.0)", + org.eclipse.jgit.revwalk;version="[4.4.2,4.5.0)", + org.eclipse.jgit.storage.file;version="[4.4.2,4.5.0)", + org.eclipse.jgit.transport;version="[4.4.2,4.5.0)", + org.eclipse.jgit.treewalk;version="[4.4.2,4.5.0)", + org.eclipse.jgit.util;version="[4.4.2,4.5.0)", + org.eclipse.jgit.util.io;version="[4.4.2,4.5.0)", org.hamcrest.core;bundle-version="[1.1.0,2.0.0)", - org.junit;version="[4.4.0,5.0.0)", + org.junit;version="[4.11.0,5.0.0)", + org.junit.rules;version="[4.11.0,5.0.0)", org.kohsuke.args4j;version="[2.0.12,2.1.0)" Require-Bundle: org.tukaani.xz;bundle-version="[1.3.0,2.0.0)" diff --git a/org.eclipse.jgit.pgm.test/pom.xml b/org.eclipse.jgit.pgm.test/pom.xml index 422532371e..eeccff4754 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.3.2-SNAPSHOT</version> + <version>4.4.2-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.pgm.test</artifactId> diff --git a/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/InitTest.java b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/InitTest.java new file mode 100644 index 0000000000..c7dbc244dd --- /dev/null +++ b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/InitTest.java @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2016, Rüdiger Herrmann <ruediger.herrmann@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.pgm; + +import static org.junit.Assert.assertArrayEquals; + +import java.io.File; + +import org.eclipse.jgit.lib.CLIRepositoryTestCase; +import org.eclipse.jgit.lib.Constants; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +public class InitTest extends CLIRepositoryTestCase { + + @Rule + public final TemporaryFolder tempFolder = new TemporaryFolder(); + + @Test + public void testInitBare() throws Exception { + File directory = tempFolder.getRoot(); + + String[] result = execute( + "git init '" + directory.getCanonicalPath() + "' --bare"); + + String[] expecteds = new String[] { + "Initialized empty Git repository in " + + directory.getCanonicalPath(), + "" }; + assertArrayEquals(expecteds, result); + } + + @Test + public void testInitDirectory() throws Exception { + File workDirectory = tempFolder.getRoot(); + File gitDirectory = new File(workDirectory, Constants.DOT_GIT); + + String[] result = execute( + "git init '" + workDirectory.getCanonicalPath() + "'"); + + String[] expecteds = new String[] { + "Initialized empty Git repository in " + + gitDirectory.getCanonicalPath(), + "" }; + assertArrayEquals(expecteds, result); + } + +} diff --git a/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF b/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF index ab0c11bd0f..cf2a03e325 100644 --- a/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Bundle-SymbolicName: org.eclipse.jgit.pgm -Bundle-Version: 4.3.2.qualifier +Bundle-Version: 4.4.2.qualifier Bundle-Vendor: %provider_name Bundle-ActivationPolicy: lazy Bundle-Localization: plugin @@ -26,45 +26,45 @@ Import-Package: javax.servlet;version="[3.1.0,4.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.3.2,4.4.0)", - org.eclipse.jgit.api.errors;version="[4.3.2,4.4.0)", - org.eclipse.jgit.archive;version="[4.3.2,4.4.0)", - org.eclipse.jgit.awtui;version="[4.3.2,4.4.0)", - org.eclipse.jgit.blame;version="[4.3.2,4.4.0)", - org.eclipse.jgit.diff;version="[4.3.2,4.4.0)", - org.eclipse.jgit.dircache;version="[4.3.2,4.4.0)", - org.eclipse.jgit.errors;version="[4.3.2,4.4.0)", - org.eclipse.jgit.gitrepo;version="[4.3.2,4.4.0)", - org.eclipse.jgit.internal.ketch;version="[4.3.2,4.4.0)", - org.eclipse.jgit.internal.storage.file;version="[4.3.2,4.4.0)", - org.eclipse.jgit.internal.storage.pack;version="[4.3.2,4.4.0)", - org.eclipse.jgit.internal.storage.reftree;version="[4.3.2,4.4.0)", - org.eclipse.jgit.lfs.lib;version="[4.3.2,4.4.0)", - org.eclipse.jgit.lfs.server;version="[4.3.2,4.4.0)", - org.eclipse.jgit.lfs.server.fs;version="[4.3.2,4.4.0)", - org.eclipse.jgit.lfs.server.s3;version="[4.3.2,4.4.0)", - org.eclipse.jgit.lib;version="[4.3.2,4.4.0)", - org.eclipse.jgit.merge;version="[4.3.2,4.4.0)", - org.eclipse.jgit.nls;version="[4.3.2,4.4.0)", - org.eclipse.jgit.notes;version="[4.3.2,4.4.0)", - org.eclipse.jgit.revplot;version="[4.3.2,4.4.0)", - org.eclipse.jgit.revwalk;version="[4.3.2,4.4.0)", - org.eclipse.jgit.revwalk.filter;version="[4.3.2,4.4.0)", - org.eclipse.jgit.storage.file;version="[4.3.2,4.4.0)", - org.eclipse.jgit.storage.pack;version="[4.3.2,4.4.0)", - org.eclipse.jgit.transport;version="[4.3.2,4.4.0)", - org.eclipse.jgit.transport.http.apache;version="[4.3.2,4.4.0)", - org.eclipse.jgit.transport.resolver;version="[4.3.2,4.4.0)", - org.eclipse.jgit.treewalk;version="[4.3.2,4.4.0)", - org.eclipse.jgit.treewalk.filter;version="[4.3.2,4.4.0)", - org.eclipse.jgit.util;version="[4.3.2,4.4.0)", - org.eclipse.jgit.util.io;version="[4.3.2,4.4.0)", + org.eclipse.jgit.api;version="[4.4.2,4.5.0)", + org.eclipse.jgit.api.errors;version="[4.4.2,4.5.0)", + org.eclipse.jgit.archive;version="[4.4.2,4.5.0)", + org.eclipse.jgit.awtui;version="[4.4.2,4.5.0)", + org.eclipse.jgit.blame;version="[4.4.2,4.5.0)", + org.eclipse.jgit.diff;version="[4.4.2,4.5.0)", + org.eclipse.jgit.dircache;version="[4.4.2,4.5.0)", + org.eclipse.jgit.errors;version="[4.4.2,4.5.0)", + org.eclipse.jgit.gitrepo;version="[4.4.2,4.5.0)", + org.eclipse.jgit.internal.ketch;version="[4.4.2,4.5.0)", + org.eclipse.jgit.internal.storage.file;version="[4.4.2,4.5.0)", + org.eclipse.jgit.internal.storage.pack;version="[4.4.2,4.5.0)", + org.eclipse.jgit.internal.storage.reftree;version="[4.4.2,4.5.0)", + org.eclipse.jgit.lfs.lib;version="[4.4.2,4.5.0)", + org.eclipse.jgit.lfs.server;version="[4.4.2,4.5.0)", + org.eclipse.jgit.lfs.server.fs;version="[4.4.2,4.5.0)", + org.eclipse.jgit.lfs.server.s3;version="[4.4.2,4.5.0)", + org.eclipse.jgit.lib;version="[4.4.2,4.5.0)", + org.eclipse.jgit.merge;version="[4.4.2,4.5.0)", + org.eclipse.jgit.nls;version="[4.4.2,4.5.0)", + org.eclipse.jgit.notes;version="[4.4.2,4.5.0)", + org.eclipse.jgit.revplot;version="[4.4.2,4.5.0)", + org.eclipse.jgit.revwalk;version="[4.4.2,4.5.0)", + org.eclipse.jgit.revwalk.filter;version="[4.4.2,4.5.0)", + org.eclipse.jgit.storage.file;version="[4.4.2,4.5.0)", + org.eclipse.jgit.storage.pack;version="[4.4.2,4.5.0)", + org.eclipse.jgit.transport;version="[4.4.2,4.5.0)", + org.eclipse.jgit.transport.http.apache;version="[4.4.2,4.5.0)", + org.eclipse.jgit.transport.resolver;version="[4.4.2,4.5.0)", + org.eclipse.jgit.treewalk;version="[4.4.2,4.5.0)", + org.eclipse.jgit.treewalk.filter;version="[4.4.2,4.5.0)", + org.eclipse.jgit.util;version="[4.4.2,4.5.0)", + org.eclipse.jgit.util.io;version="[4.4.2,4.5.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.3.2"; +Export-Package: org.eclipse.jgit.console;version="4.4.2"; uses:="org.eclipse.jgit.transport, org.eclipse.jgit.util", - org.eclipse.jgit.pgm;version="4.3.2"; + org.eclipse.jgit.pgm;version="4.4.2"; uses:="org.eclipse.jgit.revwalk, org.eclipse.jgit.treewalk.filter, org.eclipse.jgit.pgm.opt, @@ -75,11 +75,11 @@ Export-Package: org.eclipse.jgit.console;version="4.3.2"; org.eclipse.jgit.treewalk, javax.swing, org.eclipse.jgit.transport", - org.eclipse.jgit.pgm.debug;version="4.3.2"; + org.eclipse.jgit.pgm.debug;version="4.4.2"; uses:="org.eclipse.jgit.util.io, org.eclipse.jgit.pgm", - org.eclipse.jgit.pgm.internal;version="4.3.2";x-friends:="org.eclipse.jgit.pgm.test,org.eclipse.jgit.test", - org.eclipse.jgit.pgm.opt;version="4.3.2"; + org.eclipse.jgit.pgm.internal;version="4.4.2";x-friends:="org.eclipse.jgit.pgm.test,org.eclipse.jgit.test", + org.eclipse.jgit.pgm.opt;version="4.4.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 3bbff12e19..aeb8b379ba 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.3.2.qualifier -Eclipse-SourceBundle: org.eclipse.jgit.pgm;version="4.3.2.qualifier";roots="." +Bundle-Version: 4.4.2.qualifier +Eclipse-SourceBundle: org.eclipse.jgit.pgm;version="4.4.2.qualifier";roots="." diff --git a/org.eclipse.jgit.pgm/pom.xml b/org.eclipse.jgit.pgm/pom.xml index 8edb94a4ce..f469cc2c06 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.3.2-SNAPSHOT</version> + <version>4.4.2-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.pgm</artifactId> diff --git a/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties b/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties index fc412ba56f..abe04b8885 100644 --- a/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties +++ b/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties @@ -211,7 +211,6 @@ untrackedFiles=Untracked files: updating=Updating {0}..{1} usage_Aggressive=This option will cause gc to more aggressively optimize the repository at the expense of taking much more time usage_bareClone=Make a bare Git repository. That is, instead of creating [DIRECTORY] and placing the administrative files in [DIRECTORY]/.git, make the [DIRECTORY] itself the $GIT_DIR. -usage_branches=Set branch field in .gitmodules usage_Blame=Show what revision and author last modified each line usage_CommandLineClientForamazonsS3Service=Command line client for Amazon's S3 service usage_CommitAll=commit all modified and deleted files diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Branch.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Branch.java index bf6ee3a945..5f3740cbba 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Branch.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Branch.java @@ -169,7 +169,7 @@ class Branch extends TextBuiltin { if (rename) { String src, dst; if (otherBranch == null) { - final Ref head = db.getRef(Constants.HEAD); + final Ref head = db.exactRef(Constants.HEAD); if (head != null && head.isSymbolic()) { src = head.getLeaf().getName(); } else { @@ -178,7 +178,7 @@ class Branch extends TextBuiltin { dst = branch; } else { src = branch; - final Ref old = db.getRef(src); + final Ref old = db.findRef(src); if (old == null) throw die(MessageFormat.format(CLIText.get().doesNotExist, src)); if (!old.getName().startsWith(Constants.R_HEADS)) @@ -204,7 +204,7 @@ class Branch extends TextBuiltin { } else { startBranch = Constants.HEAD; } - Ref startRef = db.getRef(startBranch); + Ref startRef = db.findRef(startBranch); ObjectId startAt = db.resolve(startBranch + "^0"); //$NON-NLS-1$ if (startRef != null) { startBranch = startRef.getName(); @@ -243,7 +243,7 @@ class Branch extends TextBuiltin { } private void list() throws Exception { - Ref head = db.getRef(Constants.HEAD); + Ref head = db.exactRef(Constants.HEAD); // This can happen if HEAD is stillborn if (head != null) { String current = head.getLeaf().getName(); diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Commit.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Commit.java index 38d8d70cef..2cfbd86fa3 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Commit.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Commit.java @@ -95,7 +95,7 @@ class Commit extends TextBuiltin { commitCmd.setOnly(p); commitCmd.setAmend(amend); commitCmd.setAll(all); - Ref head = db.getRef(Constants.HEAD); + Ref head = db.exactRef(Constants.HEAD); if (head == null) { throw die(CLIText.get().onBranchToBeBorn); } diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Init.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Init.java index b3e73b5d99..a7bee7f7b9 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Init.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Init.java @@ -4,6 +4,7 @@ * Copyright (C) 2010, Robin Rosenberg <robin.rosenberg@dewire.com> * Copyright (C) 2010, Sasa Zivkov <sasa.zivkov@sap.com> * Copyright (C) 2010, Chris Aniszczyk <caniszczyk@gmail.com> + * Copyright (C) 2016, Rüdiger Herrmann <ruediger.herrmann@gmx.de> * and other copyright owners as documented in the project's IP log. * * This program and the accompanying materials are made available @@ -54,6 +55,7 @@ import org.eclipse.jgit.api.Git; import org.eclipse.jgit.api.InitCommand; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.pgm.internal.CLIText; +import org.kohsuke.args4j.Argument; import org.kohsuke.args4j.Option; @Command(common = true, usage = "usage_CreateAnEmptyGitRepository") @@ -61,6 +63,9 @@ class Init extends TextBuiltin { @Option(name = "--bare", usage = "usage_CreateABareRepository") private boolean bare; + @Argument(index = 0, metaVar = "metaVar_directory") + private String directory; + @Override protected final boolean requiresRepository() { return false; @@ -70,8 +75,12 @@ class Init extends TextBuiltin { protected void run() throws Exception { InitCommand command = Git.init(); command.setBare(bare); - if (gitdir != null) + if (gitdir != null) { command.setDirectory(new File(gitdir)); + } + if (directory != null) { + command.setDirectory(new File(directory)); + } Repository repository = command.call().getRepository(); outw.println(MessageFormat.format( CLIText.get().initializedEmptyGitRepositoryIn, repository diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Log.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Log.java index 6947cdd100..62e77285b9 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Log.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Log.java @@ -228,7 +228,7 @@ class Log extends RevWalkTextBuiltin { } private void addNoteMap(String notesRef) throws IOException { - Ref notes = db.getRef(notesRef); + Ref notes = db.exactRef(notesRef); if (notes == null) return; RevCommit notesCommit = argWalk.parseCommit(notes.getObjectId()); 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 e739b58ae7..485efc5428 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 @@ -114,7 +114,7 @@ class Merge extends TextBuiltin { } // determine the other revision we want to merge with HEAD - final Ref srcRef = db.getRef(ref); + final Ref srcRef = db.findRef(ref); final ObjectId src = db.resolve(ref + "^{commit}"); //$NON-NLS-1$ if (src == null) throw die(MessageFormat.format( @@ -209,7 +209,7 @@ class Merge extends TextBuiltin { } private Ref getOldHead() throws IOException { - Ref oldHead = db.getRef(Constants.HEAD); + Ref oldHead = db.exactRef(Constants.HEAD); if (oldHead == null) { throw die(CLIText.get().onBranchToBeBorn); } diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Repo.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Repo.java index ea59527fed..bec5003a1e 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Repo.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Repo.java @@ -58,16 +58,12 @@ class Repo extends TextBuiltin { @Argument(required = true, metaVar = "metaVar_path", usage = "usage_pathToXml") private String path; - @Option(name = "--record-remote-branch", usage = "usage_branches") - private boolean branches; - @Override protected void run() throws Exception { new RepoCommand(db) .setURI(uri) .setPath(path) .setGroups(groups) - .setRecordRemoteBranch(branches) .call(); } } diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Show.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Show.java index c5986b01aa..6892c9973f 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Show.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Show.java @@ -63,6 +63,7 @@ import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.FileMode; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.PersonIdent; +import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.pgm.internal.CLIText; import org.eclipse.jgit.pgm.opt.PathTreeFilterHandler; import org.eclipse.jgit.revwalk.RevCommit; @@ -81,8 +82,7 @@ class Show extends TextBuiltin { private final DateFormat fmt; - private final DiffFormatter diffFmt = new DiffFormatter( // - new BufferedOutputStream(System.out)); + private DiffFormatter diffFmt; @Argument(index = 0, metaVar = "metaVar_object") private String objectName; @@ -165,6 +165,12 @@ class Show extends TextBuiltin { fmt = new SimpleDateFormat("EEE MMM dd HH:mm:ss yyyy ZZZZZ", Locale.US); //$NON-NLS-1$ } + @Override + protected void init(final Repository repository, final String gitDir) { + super.init(repository, gitDir); + diffFmt = new DiffFormatter(new BufferedOutputStream(outs)); + } + @SuppressWarnings("boxing") @Override protected void run() throws Exception { 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 6a6322131a..de3df806d8 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 @@ -204,7 +204,7 @@ class Status extends TextBuiltin { private void printLongStatus(org.eclipse.jgit.api.Status status) throws IOException { // Print current branch name - final Ref head = db.getRef(Constants.HEAD); + final Ref head = db.exactRef(Constants.HEAD); if (head != null && head.isSymbolic()) { String branch = Repository.shortenRefName(head.getLeaf().getName()); outw.println(CLIText.formatLine(MessageFormat.format( diff --git a/org.eclipse.jgit.test/META-INF/MANIFEST.MF b/org.eclipse.jgit.test/META-INF/MANIFEST.MF index 4c47ce5b58..12620de39d 100644 --- a/org.eclipse.jgit.test/META-INF/MANIFEST.MF +++ b/org.eclipse.jgit.test/META-INF/MANIFEST.MF @@ -2,55 +2,56 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %plugin_name Bundle-SymbolicName: org.eclipse.jgit.test -Bundle-Version: 4.3.2.qualifier +Bundle-Version: 4.4.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.3.2,4.4.0)", - org.eclipse.jgit.api.errors;version="[4.3.2,4.4.0)", - org.eclipse.jgit.attributes;version="[4.3.2,4.4.0)", - org.eclipse.jgit.awtui;version="[4.3.2,4.4.0)", - org.eclipse.jgit.blame;version="[4.3.2,4.4.0)", - org.eclipse.jgit.diff;version="[4.3.2,4.4.0)", - org.eclipse.jgit.dircache;version="[4.3.2,4.4.0)", - org.eclipse.jgit.errors;version="[4.3.2,4.4.0)", - org.eclipse.jgit.events;version="[4.3.2,4.4.0)", - org.eclipse.jgit.fnmatch;version="[4.3.2,4.4.0)", - org.eclipse.jgit.gitrepo;version="[4.3.2,4.4.0)", - org.eclipse.jgit.hooks;version="[4.3.2,4.4.0)", - org.eclipse.jgit.ignore;version="[4.3.2,4.4.0)", - org.eclipse.jgit.ignore.internal;version="[4.3.2,4.4.0)", - org.eclipse.jgit.internal;version="[4.3.2,4.4.0)", - org.eclipse.jgit.internal.storage.dfs;version="[4.3.2,4.4.0)", - org.eclipse.jgit.internal.storage.file;version="[4.3.2,4.4.0)", - org.eclipse.jgit.internal.storage.pack;version="[4.3.2,4.4.0)", - org.eclipse.jgit.internal.storage.reftree;version="[4.3.2,4.4.0)", - org.eclipse.jgit.junit;version="[4.3.2,4.4.0)", - org.eclipse.jgit.lib;version="[4.3.2,4.4.0)", - org.eclipse.jgit.merge;version="[4.3.2,4.4.0)", - org.eclipse.jgit.nls;version="[4.3.2,4.4.0)", - org.eclipse.jgit.notes;version="[4.3.2,4.4.0)", - org.eclipse.jgit.patch;version="[4.3.2,4.4.0)", - org.eclipse.jgit.pgm;version="[4.3.2,4.4.0)", - org.eclipse.jgit.pgm.internal;version="[4.3.2,4.4.0)", - org.eclipse.jgit.revplot;version="[4.3.2,4.4.0)", - org.eclipse.jgit.revwalk;version="[4.3.2,4.4.0)", - org.eclipse.jgit.revwalk.filter;version="[4.3.2,4.4.0)", - org.eclipse.jgit.storage.file;version="[4.3.2,4.4.0)", - org.eclipse.jgit.storage.pack;version="[4.3.2,4.4.0)", - org.eclipse.jgit.submodule;version="[4.3.2,4.4.0)", - org.eclipse.jgit.transport;version="[4.3.2,4.4.0)", - org.eclipse.jgit.transport.http;version="[4.3.2,4.4.0)", - org.eclipse.jgit.transport.resolver;version="[4.3.2,4.4.0)", - org.eclipse.jgit.treewalk;version="[4.3.2,4.4.0)", - org.eclipse.jgit.treewalk.filter;version="[4.3.2,4.4.0)", - org.eclipse.jgit.util;version="[4.3.2,4.4.0)", - org.eclipse.jgit.util.io;version="[4.3.2,4.4.0)", + org.eclipse.jgit.api;version="[4.4.2,4.5.0)", + org.eclipse.jgit.api.errors;version="[4.4.2,4.5.0)", + org.eclipse.jgit.attributes;version="[4.4.2,4.5.0)", + org.eclipse.jgit.awtui;version="[4.4.2,4.5.0)", + org.eclipse.jgit.blame;version="[4.4.2,4.5.0)", + org.eclipse.jgit.diff;version="[4.4.2,4.5.0)", + org.eclipse.jgit.dircache;version="[4.4.2,4.5.0)", + org.eclipse.jgit.errors;version="[4.4.2,4.5.0)", + org.eclipse.jgit.events;version="[4.4.2,4.5.0)", + org.eclipse.jgit.fnmatch;version="[4.4.2,4.5.0)", + org.eclipse.jgit.gitrepo;version="[4.4.2,4.5.0)", + org.eclipse.jgit.hooks;version="[4.4.2,4.5.0)", + org.eclipse.jgit.ignore;version="[4.4.2,4.5.0)", + org.eclipse.jgit.ignore.internal;version="[4.4.2,4.5.0)", + org.eclipse.jgit.internal;version="[4.4.2,4.5.0)", + org.eclipse.jgit.internal.storage.dfs;version="[4.4.2,4.5.0)", + org.eclipse.jgit.internal.storage.file;version="[4.4.2,4.5.0)", + org.eclipse.jgit.internal.storage.pack;version="[4.4.2,4.5.0)", + org.eclipse.jgit.internal.storage.reftree;version="[4.4.2,4.5.0)", + org.eclipse.jgit.junit;version="[4.4.2,4.5.0)", + org.eclipse.jgit.lib;version="[4.4.2,4.5.0)", + org.eclipse.jgit.merge;version="[4.4.2,4.5.0)", + org.eclipse.jgit.nls;version="[4.4.2,4.5.0)", + org.eclipse.jgit.notes;version="[4.4.2,4.5.0)", + org.eclipse.jgit.patch;version="[4.4.2,4.5.0)", + org.eclipse.jgit.pgm;version="[4.4.2,4.5.0)", + org.eclipse.jgit.pgm.internal;version="[4.4.2,4.5.0)", + org.eclipse.jgit.revplot;version="[4.4.2,4.5.0)", + org.eclipse.jgit.revwalk;version="[4.4.2,4.5.0)", + org.eclipse.jgit.revwalk.filter;version="[4.4.2,4.5.0)", + org.eclipse.jgit.storage.file;version="[4.4.2,4.5.0)", + org.eclipse.jgit.storage.pack;version="[4.4.2,4.5.0)", + org.eclipse.jgit.submodule;version="[4.4.2,4.5.0)", + org.eclipse.jgit.transport;version="[4.4.2,4.5.0)", + org.eclipse.jgit.transport.http;version="[4.4.2,4.5.0)", + org.eclipse.jgit.transport.resolver;version="[4.4.2,4.5.0)", + org.eclipse.jgit.treewalk;version="[4.4.2,4.5.0)", + org.eclipse.jgit.treewalk.filter;version="[4.4.2,4.5.0)", + org.eclipse.jgit.util;version="[4.4.2,4.5.0)", + org.eclipse.jgit.util.io;version="[4.4.2,4.5.0)", org.hamcrest;version="[1.1.0,2.0.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)" diff --git a/org.eclipse.jgit.test/pom.xml b/org.eclipse.jgit.test/pom.xml index a52ac4c075..81a3b09418 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.3.2-SNAPSHOT</version> + <version>4.4.2-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.test</artifactId> diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/M1.patch b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/M1.patch new file mode 100644 index 0000000000..395bd4c503 --- /dev/null +++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/M1.patch @@ -0,0 +1,9 @@ +diff --git a/M1 b/M1 +new file mode 100755 +index 0000000..de98044 +--- /dev/null ++++ b/M1 +@@ -0,0 +1,3 @@ ++a ++b ++c diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/M1_PostImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/M1_PostImage new file mode 100644 index 0000000000..de980441c3 --- /dev/null +++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/M1_PostImage @@ -0,0 +1,3 @@ +a +b +c diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/M2.patch b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/M2.patch new file mode 100644 index 0000000000..b56ca0828e --- /dev/null +++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/M2.patch @@ -0,0 +1,10 @@ +diff --git a/M2 b/M2 +old mode 100644 +new mode 100755 +index 0000000..de98044 +--- a/M2 ++++ b/M2 +@@ -1,3 +1,1 @@ + a +-b +-c diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/M2_PostImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/M2_PostImage new file mode 100644 index 0000000000..7898192261 --- /dev/null +++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/M2_PostImage @@ -0,0 +1 @@ +a diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/M2_PreImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/M2_PreImage new file mode 100644 index 0000000000..de980441c3 --- /dev/null +++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/M2_PreImage @@ -0,0 +1,3 @@ +a +b +c diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/M3.patch b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/M3.patch new file mode 100644 index 0000000000..ee536058ab --- /dev/null +++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/M3.patch @@ -0,0 +1,10 @@ +diff --git a/M3 b/M3 +old mode 100755 +new mode 100644 +index 0000000..de98044 +--- a/M3 ++++ b/M3 +@@ -1,1 +1,3 @@ + a ++b ++c diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/M3_PostImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/M3_PostImage new file mode 100644 index 0000000000..de980441c3 --- /dev/null +++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/M3_PostImage @@ -0,0 +1,3 @@ +a +b +c diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/M3_PreImage b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/M3_PreImage new file mode 100755 index 0000000000..7898192261 --- /dev/null +++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/diff/M3_PreImage @@ -0,0 +1 @@ +a diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ApplyCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ApplyCommandTest.java index f2b5b3ba95..172807c43d 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ApplyCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ApplyCommandTest.java @@ -44,6 +44,7 @@ package org.eclipse.jgit.api; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.ByteArrayOutputStream; @@ -157,6 +158,33 @@ public class ApplyCommandTest extends RepositoryTestCase { } @Test + public void testAddM1() throws Exception { + ApplyResult result = init("M1", false, true); + assertEquals(1, result.getUpdatedFiles().size()); + assertTrue(result.getUpdatedFiles().get(0).canExecute()); + checkFile(new File(db.getWorkTree(), "M1"), + b.getString(0, b.size(), false)); + } + + @Test + public void testModifyM2() throws Exception { + ApplyResult result = init("M2", true, true); + assertEquals(1, result.getUpdatedFiles().size()); + assertTrue(result.getUpdatedFiles().get(0).canExecute()); + checkFile(new File(db.getWorkTree(), "M2"), + b.getString(0, b.size(), false)); + } + + @Test + public void testModifyM3() throws Exception { + ApplyResult result = init("M3", true, true); + assertEquals(1, result.getUpdatedFiles().size()); + assertFalse(result.getUpdatedFiles().get(0).canExecute()); + checkFile(new File(db.getWorkTree(), "M3"), + b.getString(0, b.size(), false)); + } + + @Test public void testModifyX() throws Exception { ApplyResult result = init("X"); assertEquals(1, result.getUpdatedFiles().size()); 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 9d87f0c29c..8a07118f84 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 @@ -68,6 +68,7 @@ import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.PersonIdent; import org.eclipse.jgit.lib.RefUpdate; import org.eclipse.jgit.lib.RefUpdate.Result; +import org.eclipse.jgit.lib.ReflogEntry; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.StoredConfig; import org.eclipse.jgit.revwalk.RevCommit; @@ -436,6 +437,36 @@ public class CommitCommandTest extends RepositoryTestCase { } } + @Test + public void testReflogs() throws Exception { + try (Git git = new Git(db)) { + writeTrashFile("f", "1"); + git.add().addFilepattern("f").call(); + git.commit().setMessage("c1").call(); + writeTrashFile("f", "2"); + git.commit().setMessage("c2").setAll(true).setReflogComment(null) + .call(); + writeTrashFile("f", "3"); + git.commit().setMessage("c3").setAll(true) + .setReflogComment("testRl").call(); + + db.getReflogReader(Constants.HEAD).getReverseEntries(); + + assertEquals("testRl;commit (initial): c1;", reflogComments( + db.getReflogReader(Constants.HEAD).getReverseEntries())); + assertEquals("testRl;commit (initial): c1;", reflogComments( + db.getReflogReader(db.getBranch()).getReverseEntries())); + } + } + + private static String reflogComments(List<ReflogEntry> entries) { + StringBuffer b = new StringBuffer(); + for (ReflogEntry e : entries) { + b.append(e.getComment()).append(";"); + } + return b.toString(); + } + @Test(expected = WrongRepositoryStateException.class) public void commitAmendOnInitialShouldFail() throws Exception { try (Git git = new Git(db)) { diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/LogCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/LogCommandTest.java index 34432c588b..1310625a9b 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/LogCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/LogCommandTest.java @@ -53,7 +53,9 @@ import java.util.List; import org.eclipse.jgit.junit.RepositoryTestCase; import org.eclipse.jgit.lib.PersonIdent; import org.eclipse.jgit.lib.Ref; +import org.eclipse.jgit.merge.MergeStrategy; import org.eclipse.jgit.revwalk.RevCommit; +import org.eclipse.jgit.revwalk.filter.RevFilter; import org.junit.Test; public class LogCommandTest extends RepositoryTestCase { @@ -210,4 +212,81 @@ public class LogCommandTest extends RepositoryTestCase { assertEquals("commit#2", commit.getShortMessage()); assertFalse(log.hasNext()); } + + @Test + public void logOnlyMergeCommits() throws Exception { + setCommitsAndMerge(); + Git git = Git.wrap(db); + + Iterable<RevCommit> commits = git.log().all().call(); + Iterator<RevCommit> i = commits.iterator(); + RevCommit commit = i.next(); + assertEquals("merge s0 with m1", commit.getFullMessage()); + commit = i.next(); + assertEquals("s0", commit.getFullMessage()); + commit = i.next(); + assertEquals("m1", commit.getFullMessage()); + commit = i.next(); + assertEquals("m0", commit.getFullMessage()); + assertFalse(i.hasNext()); + + commits = git.log().setRevFilter(RevFilter.ONLY_MERGES).call(); + i = commits.iterator(); + commit = i.next(); + assertEquals("merge s0 with m1", commit.getFullMessage()); + assertFalse(i.hasNext()); + } + + @Test + public void logNoMergeCommits() throws Exception { + setCommitsAndMerge(); + Git git = Git.wrap(db); + + Iterable<RevCommit> commits = git.log().all().call(); + Iterator<RevCommit> i = commits.iterator(); + RevCommit commit = i.next(); + assertEquals("merge s0 with m1", commit.getFullMessage()); + commit = i.next(); + assertEquals("s0", commit.getFullMessage()); + commit = i.next(); + assertEquals("m1", commit.getFullMessage()); + commit = i.next(); + assertEquals("m0", commit.getFullMessage()); + assertFalse(i.hasNext()); + + commits = git.log().setRevFilter(RevFilter.NO_MERGES).call(); + i = commits.iterator(); + commit = i.next(); + assertEquals("m1", commit.getFullMessage()); + commit = i.next(); + assertEquals("s0", commit.getFullMessage()); + commit = i.next(); + assertEquals("m0", commit.getFullMessage()); + assertFalse(i.hasNext()); + } + + private void setCommitsAndMerge() throws Exception { + Git git = Git.wrap(db); + writeTrashFile("file1", "1\n2\n3\n4\n"); + git.add().addFilepattern("file1").call(); + RevCommit masterCommit0 = git.commit().setMessage("m0").call(); + + createBranch(masterCommit0, "refs/heads/side"); + checkoutBranch("refs/heads/side"); + + writeTrashFile("file2", "1\n2\n3\n4\n5\n6\n7\n8\n"); + git.add().addFilepattern("file2").call(); + RevCommit c = git.commit().setMessage("s0").call(); + + checkoutBranch("refs/heads/master"); + + writeTrashFile("file3", "1\n2\n"); + git.add().addFilepattern("file3").call(); + git.commit().setMessage("m1").call(); + + git.merge().include(c.getId()) + .setStrategy(MergeStrategy.RESOLVE) + .setMessage("merge s0 with m1").call(); + } + }
\ No newline at end of file diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PullCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PullCommandTest.java index ff7066e8bf..a526fdaa7e 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PullCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PullCommandTest.java @@ -58,6 +58,7 @@ import java.util.concurrent.Callable; import org.eclipse.jgit.api.CreateBranchCommand.SetupUpstreamMode; import org.eclipse.jgit.api.MergeResult.MergeStatus; import org.eclipse.jgit.api.errors.NoHeadException; +import org.eclipse.jgit.junit.JGitTestUtil; import org.eclipse.jgit.junit.RepositoryTestCase; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.ObjectId; @@ -185,6 +186,40 @@ public class PullCommandTest extends RepositoryTestCase { } @Test + public void testPullWithUntrackedStash() throws Exception { + target.pull().call(); + + // change the source file + writeToFile(sourceFile, "Source change"); + source.add().addFilepattern("SomeFile.txt").call(); + source.commit().setMessage("Source change in remote").call(); + + // write untracked file + writeToFile(new File(dbTarget.getWorkTree(), "untracked.txt"), + "untracked"); + RevCommit stash = target.stashCreate().setIndexMessage("message here") + .setIncludeUntracked(true).call(); + assertNotNull(stash); + assertTrue(target.status().call().isClean()); + + // pull from source + assertTrue(target.pull().call().isSuccessful()); + assertEquals("[SomeFile.txt, mode:100644, content:Source change]", + indexState(dbTarget, CONTENT)); + assertFalse(JGitTestUtil.check(dbTarget, "untracked.txt")); + assertEquals("Source change", + JGitTestUtil.read(dbTarget, "SomeFile.txt")); + + // apply the stash + target.stashApply().setStashRef(stash.getName()).call(); + assertEquals("[SomeFile.txt, mode:100644, content:Source change]", + indexState(dbTarget, CONTENT)); + assertEquals("untracked", JGitTestUtil.read(dbTarget, "untracked.txt")); + assertEquals("Source change", + JGitTestUtil.read(dbTarget, "SomeFile.txt")); + } + + @Test public void testPullLocalConflict() throws Exception { target.branchCreate().setName("basedOnMaster").setStartPoint( "refs/heads/master").setUpstreamMode(SetupUpstreamMode.TRACK) @@ -576,4 +611,4 @@ public class PullCommandTest extends RepositoryTestCase { fis.close(); } } -} +}
\ No newline at end of file diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ResetCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ResetCommandTest.java index 40d8458efd..a4a699ef22 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ResetCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/ResetCommandTest.java @@ -157,6 +157,34 @@ public class ResetCommandTest extends RepositoryTestCase { } @Test + public void testHardResetWithConflicts_DoOverWriteUntrackedFile() + throws JGitInternalException, + AmbiguousObjectException, IOException, GitAPIException { + setupRepository(); + git.rm().setCached(true).addFilepattern("a.txt").call(); + assertTrue(new File(db.getWorkTree(), "a.txt").exists()); + git.reset().setMode(ResetType.HARD).setRef(Constants.HEAD) + .call(); + assertTrue(new File(db.getWorkTree(), "a.txt").exists()); + assertEquals("content", read(new File(db.getWorkTree(), "a.txt"))); + } + + @Test + public void testHardResetWithConflicts_DoDeleteFileFolderConflicts() + throws JGitInternalException, + AmbiguousObjectException, IOException, GitAPIException { + setupRepository(); + writeTrashFile("d/c.txt", "x"); + git.add().addFilepattern("d/c.txt").call(); + FileUtils.delete(new File(db.getWorkTree(), "d"), FileUtils.RECURSIVE); + writeTrashFile("d", "y"); + + git.reset().setMode(ResetType.HARD).setRef(Constants.HEAD) + .call(); + assertFalse(new File(db.getWorkTree(), "d").exists()); + } + + @Test public void testResetToNonexistingHEAD() throws JGitInternalException, AmbiguousObjectException, IOException, GitAPIException { @@ -568,7 +596,7 @@ public class ResetCommandTest extends RepositoryTestCase { * @throws IOException */ private void assertSameAsHead(Ref ref) throws IOException { - Ref headRef = db.getRef(Constants.HEAD); + Ref headRef = db.exactRef(Constants.HEAD); assertEquals(headRef.getName(), ref.getName()); assertEquals(headRef.getObjectId(), ref.getObjectId()); } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/RepoCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/RepoCommandTest.java index 2cec34ba89..ccd15d038d 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/RepoCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/RepoCommandTest.java @@ -44,6 +44,7 @@ package org.eclipse.jgit.gitrepo; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import java.io.BufferedReader; @@ -743,14 +744,107 @@ public class RepoCommandTest extends RepositoryTestCase { FileBasedConfig c = new FileBasedConfig(gitmodules, FS.DETECTED); c.load(); - assertEquals("standard branches work", "master", + assertEquals("Recording remote branches should work for short branch descriptions", "master", c.getString("submodule", "with-branch", "branch")); - assertEquals("long branches work", "refs/heads/master", + assertEquals("Recording remote branches should work for full ref specs", "refs/heads/master", c.getString("submodule", "with-long-branch", "branch")); } } } + + @Test + public void testRecordSubmoduleLabels() throws Exception { + try ( + Repository remoteDb = createBareRepository(); + Repository tempDb = createWorkRepository()) { + StringBuilder xmlContent = new StringBuilder(); + xmlContent + .append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") + .append("<manifest>") + .append("<remote name=\"remote1\" fetch=\".\" />") + .append("<default revision=\"master\" remote=\"remote1\" />") + .append("<project path=\"test\" ") + .append("revision=\"master\" ") + .append("name=\"").append(notDefaultUri).append("\" ") + .append("groups=\"a1,a2\" />") + .append("</manifest>"); + JGitTestUtil.writeTrashFile(tempDb, "manifest.xml", + xmlContent.toString()); + + RepoCommand command = new RepoCommand(remoteDb); + command.setPath(tempDb.getWorkTree().getAbsolutePath() + "/manifest.xml") + .setURI(rootUri) + .setRecordSubmoduleLabels(true) + .call(); + // Clone it + File directory = createTempDirectory("testBareRepo"); + try (Repository localDb = Git.cloneRepository() + .setDirectory(directory) + .setURI(remoteDb.getDirectory().toURI().toString()).call() + .getRepository();) { + // The .gitattributes file should exist + File gitattributes = new File(localDb.getWorkTree(), + ".gitattributes"); + assertTrue("The .gitattributes file should exist", + gitattributes.exists()); + try (BufferedReader reader = new BufferedReader( + new FileReader(gitattributes));) { + String content = reader.readLine(); + assertEquals(".gitattributes content should be as expected", + "/test a1 a2", content); + } + } + } + } + + @Test + public void testRecordShallowRecommendation() throws Exception { + try ( + Repository remoteDb = createBareRepository(); + Repository tempDb = createWorkRepository()) { + StringBuilder xmlContent = new StringBuilder(); + xmlContent + .append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") + .append("<manifest>") + .append("<remote name=\"remote1\" fetch=\".\" />") + .append("<default revision=\"master\" remote=\"remote1\" />") + .append("<project path=\"shallow-please\" ") + .append("name=\"").append(defaultUri).append("\" ") + .append("clone-depth=\"1\" />") + .append("<project path=\"non-shallow\" ") + .append("name=\"").append(defaultUri).append("\" />") + .append("</manifest>"); + JGitTestUtil.writeTrashFile(tempDb, "manifest.xml", + xmlContent.toString()); + + RepoCommand command = new RepoCommand(remoteDb); + command.setPath(tempDb.getWorkTree().getAbsolutePath() + "/manifest.xml") + .setURI(rootUri) + .setRecommendShallow(true) + .call(); + // Clone it + File directory = createTempDirectory("testBareRepo"); + try (Repository localDb = Git.cloneRepository() + .setDirectory(directory) + .setURI(remoteDb.getDirectory().toURI().toString()).call() + .getRepository();) { + // The .gitmodules file should exist + File gitmodules = new File(localDb.getWorkTree(), + ".gitmodules"); + assertTrue("The .gitmodules file should exist", + gitmodules.exists()); + FileBasedConfig c = new FileBasedConfig(gitmodules, + FS.DETECTED); + c.load(); + assertEquals("Recording shallow configuration should work", "true", + c.getString("submodule", "shallow-please", "shallow")); + assertNull("Recording non shallow configuration should work", + c.getString("submodule", "non-shallow", "shallow")); + } + } + } + @Test public void testRemoteRevision() throws Exception { StringBuilder xmlContent = new StringBuilder(); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsInserterTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsInserterTest.java index 11a092468c..74790f72c5 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsInserterTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsInserterTest.java @@ -45,6 +45,7 @@ package org.eclipse.jgit.internal.storage.dfs; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import java.io.IOException; @@ -97,6 +98,7 @@ public class DfsInserterTest { assertEquals(0, db.getObjectDatabase().listPacks().size()); ObjectReader reader = ins.newReader(); + assertSame(ins, reader.getCreatedFromInserter()); assertEquals("foo", readString(reader.open(id1))); assertEquals("bar", readString(reader.open(id2))); assertEquals(0, db.getObjectDatabase().listPacks().size()); @@ -118,6 +120,7 @@ public class DfsInserterTest { assertEquals(0, db.getObjectDatabase().listPacks().size()); ObjectReader reader = ins.newReader(); + assertSame(ins, reader.getCreatedFromInserter()); assertTrue(Arrays.equals(data, readStream(reader.open(id1)))); assertEquals(0, db.getObjectDatabase().listPacks().size()); ins.flush(); @@ -136,6 +139,7 @@ public class DfsInserterTest { assertEquals(1, db.getObjectDatabase().listPacks().size()); ObjectReader reader = ins.newReader(); + assertSame(ins, reader.getCreatedFromInserter()); assertEquals("foo", readString(reader.open(id1))); assertEquals("bar", readString(reader.open(id2))); assertEquals(1, db.getObjectDatabase().listPacks().size()); @@ -154,6 +158,7 @@ public class DfsInserterTest { assertFalse(abbr1.equals(abbr2)); ObjectReader reader = ins.newReader(); + assertSame(ins, reader.getCreatedFromInserter()); Collection<ObjectId> objs; objs = reader.resolve(AbbreviatedObjectId.fromString(abbr1)); assertEquals(1, objs.size()); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcPackRefsTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcPackRefsTest.java index 48ea13b98a..ea8dfa2939 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcPackRefsTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/GcPackRefsTest.java @@ -45,11 +45,14 @@ package org.eclipse.jgit.internal.storage.file; import static java.lang.Integer.valueOf; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import java.io.File; import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.Callable; import java.util.concurrent.CyclicBarrier; @@ -81,6 +84,17 @@ public class GcPackRefsTest extends GcTestCase { } @Test + public void emptyRefDirectoryDeleted() throws Exception { + String ref = "dir/ref"; + tr.branch(ref).commit().create(); + String name = repo.findRef(ref).getName(); + Path dir = repo.getDirectory().toPath().resolve(name).getParent(); + + gc.packRefs(); + assertFalse(Files.exists(dir)); + } + + @Test public void concurrentOnlyOneWritesPackedRefs() throws Exception { RevBlob a = tr.blob("a"); tr.lightweightTag("t", a); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java index 6238a354d8..aebbafeff2 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ConfigTest.java @@ -48,6 +48,11 @@ package org.eclipse.jgit.lib; +import static java.util.concurrent.TimeUnit.DAYS; +import static java.util.concurrent.TimeUnit.HOURS; +import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static java.util.concurrent.TimeUnit.MINUTES; +import static java.util.concurrent.TimeUnit.SECONDS; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -56,26 +61,41 @@ import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; import java.text.MessageFormat; import java.util.Arrays; import java.util.Iterator; import java.util.LinkedList; import java.util.Set; +import java.util.concurrent.TimeUnit; import org.eclipse.jgit.api.MergeCommand.FastForwardMode; import org.eclipse.jgit.errors.ConfigInvalidException; +import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.junit.MockSystemReader; import org.eclipse.jgit.merge.MergeConfig; +import org.eclipse.jgit.storage.file.FileBasedConfig; import org.eclipse.jgit.util.FS; import org.eclipse.jgit.util.SystemReader; import org.junit.After; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.rules.TemporaryFolder; /** * Test reading of git config */ public class ConfigTest { + @Rule + public ExpectedException expectedEx = ExpectedException.none(); + + @Rule + public TemporaryFolder tmp = new TemporaryFolder(); + @After public void tearDown() { SystemReader.setInstance(null); @@ -739,6 +759,102 @@ public class ConfigTest { c.getStringList("a", null, "x")); } + @Test + public void testReadMultipleValuesForName() throws ConfigInvalidException { + Config c = parse("[foo]\nbar=false\nbar=true\n"); + assertTrue(c.getBoolean("foo", "bar", false)); + } + + @Test + public void testIncludeInvalidName() throws ConfigInvalidException { + expectedEx.expect(ConfigInvalidException.class); + expectedEx.expectMessage(JGitText.get().invalidLineInConfigFile); + parse("[include]\nbar\n"); + } + + @Test + public void testIncludeNoValue() throws ConfigInvalidException { + expectedEx.expect(ConfigInvalidException.class); + expectedEx.expectMessage(JGitText.get().invalidLineInConfigFile); + parse("[include]\npath\n"); + } + + @Test + public void testIncludeEmptyValue() throws ConfigInvalidException { + expectedEx.expect(ConfigInvalidException.class); + expectedEx.expectMessage(JGitText.get().invalidLineInConfigFile); + parse("[include]\npath=\n"); + } + + @Test + public void testIncludeValuePathNotFound() throws ConfigInvalidException { + // we do not expect an exception, included path not found are ignored + String notFound = "/not/found"; + Config parsed = parse("[include]\npath=" + notFound + "\n"); + assertEquals(1, parsed.getSections().size()); + assertEquals(notFound, parsed.getString("include", null, "path")); + } + + @Test + public void testIncludeValuePathWithTilde() throws ConfigInvalidException { + // we do not expect an exception, included path not supported are + // ignored + String notSupported = "~/someFile"; + Config parsed = parse("[include]\npath=" + notSupported + "\n"); + assertEquals(1, parsed.getSections().size()); + assertEquals(notSupported, parsed.getString("include", null, "path")); + } + + @Test + public void testIncludeValuePathRelative() throws ConfigInvalidException { + // we do not expect an exception, included path not supported are + // ignored + String notSupported = "someRelativeFile"; + Config parsed = parse("[include]\npath=" + notSupported + "\n"); + assertEquals(1, parsed.getSections().size()); + assertEquals(notSupported, parsed.getString("include", null, "path")); + } + + @Test + public void testIncludeTooManyRecursions() throws IOException { + File config = tmp.newFile("config"); + String include = "[include]\npath=" + config.toPath() + "\n"; + Files.write(config.toPath(), include.getBytes()); + FileBasedConfig fbConfig = new FileBasedConfig(null, config, + FS.DETECTED); + try { + fbConfig.load(); + fail(); + } catch (ConfigInvalidException cie) { + assertEquals(JGitText.get().tooManyIncludeRecursions, + cie.getCause().getMessage()); + } + } + + @Test + public void testInclude() throws IOException, ConfigInvalidException { + File config = tmp.newFile("config"); + File more = tmp.newFile("config.more"); + File other = tmp.newFile("config.other"); + + String fooBar = "[foo]\nbar=true\n"; + String includeMore = "[include]\npath=" + more.toPath() + "\n"; + String includeOther = "path=" + other.toPath() + "\n"; + String fooPlus = fooBar + includeMore + includeOther; + Files.write(config.toPath(), fooPlus.getBytes()); + + String fooMore = "[foo]\nmore=bar\n"; + Files.write(more.toPath(), fooMore.getBytes()); + + String otherMore = "[other]\nmore=bar\n"; + Files.write(other.toPath(), otherMore.getBytes()); + + Config parsed = parse("[include]\npath=" + config.toPath() + "\n"); + assertTrue(parsed.getBoolean("foo", "bar", false)); + assertEquals("bar", parsed.getString("foo", null, "more")); + assertEquals("bar", parsed.getString("other", null, "more")); + } + private static void assertReadLong(long exp) throws ConfigInvalidException { assertReadLong(exp, String.valueOf(exp)); } @@ -760,4 +876,93 @@ public class ConfigTest { c.fromText(content); return c; } + + @Test + public void testTimeUnit() throws ConfigInvalidException { + assertEquals(0, parseTime("0", MILLISECONDS)); + assertEquals(2, parseTime("2ms", MILLISECONDS)); + assertEquals(200, parseTime("200 milliseconds", MILLISECONDS)); + + assertEquals(0, parseTime("0s", SECONDS)); + assertEquals(2, parseTime("2s", SECONDS)); + assertEquals(231, parseTime("231sec", SECONDS)); + assertEquals(1, parseTime("1second", SECONDS)); + assertEquals(300, parseTime("300 seconds", SECONDS)); + + assertEquals(2, parseTime("2m", MINUTES)); + assertEquals(2, parseTime("2min", MINUTES)); + assertEquals(1, parseTime("1 minute", MINUTES)); + assertEquals(10, parseTime("10 minutes", MINUTES)); + + assertEquals(5, parseTime("5h", HOURS)); + assertEquals(5, parseTime("5hr", HOURS)); + assertEquals(1, parseTime("1hour", HOURS)); + assertEquals(48, parseTime("48hours", HOURS)); + + assertEquals(5, parseTime("5 h", HOURS)); + assertEquals(5, parseTime("5 hr", HOURS)); + assertEquals(1, parseTime("1 hour", HOURS)); + assertEquals(48, parseTime("48 hours", HOURS)); + assertEquals(48, parseTime("48 \t \r hours", HOURS)); + + assertEquals(4, parseTime("4d", DAYS)); + assertEquals(1, parseTime("1day", DAYS)); + assertEquals(14, parseTime("14days", DAYS)); + + assertEquals(7, parseTime("1w", DAYS)); + assertEquals(7, parseTime("1week", DAYS)); + assertEquals(14, parseTime("2w", DAYS)); + assertEquals(14, parseTime("2weeks", DAYS)); + + assertEquals(30, parseTime("1mon", DAYS)); + assertEquals(30, parseTime("1month", DAYS)); + assertEquals(60, parseTime("2mon", DAYS)); + assertEquals(60, parseTime("2months", DAYS)); + + assertEquals(365, parseTime("1y", DAYS)); + assertEquals(365, parseTime("1year", DAYS)); + assertEquals(365 * 2, parseTime("2years", DAYS)); + } + + private long parseTime(String value, TimeUnit unit) + throws ConfigInvalidException { + Config c = parse("[a]\na=" + value + "\n"); + return c.getTimeUnit("a", null, "a", 0, unit); + } + + @Test + public void testTimeUnitDefaultValue() throws ConfigInvalidException { + // value not present + assertEquals(20, parse("[a]\na=0\n").getTimeUnit("a", null, "b", 20, + MILLISECONDS)); + // value is empty + assertEquals(20, parse("[a]\na=\" \"\n").getTimeUnit("a", null, "a", 20, + MILLISECONDS)); + + // value is not numeric + assertEquals(20, parse("[a]\na=test\n").getTimeUnit("a", null, "a", 20, + MILLISECONDS)); + } + + @Test + public void testTimeUnitInvalid() throws ConfigInvalidException { + expectedEx.expect(IllegalArgumentException.class); + expectedEx + .expectMessage("Invalid time unit value: a.a=1 monttthhh"); + parseTime("1 monttthhh", DAYS); + } + + @Test + public void testTimeUnitInvalidWithSection() throws ConfigInvalidException { + Config c = parse("[a \"b\"]\na=1 monttthhh\n"); + expectedEx.expect(IllegalArgumentException.class); + expectedEx.expectMessage("Invalid time unit value: a.b.a=1 monttthhh"); + c.getTimeUnit("a", "b", "a", 0, DAYS); + } + + @Test + public void testTimeUnitNegative() throws ConfigInvalidException { + expectedEx.expect(IllegalArgumentException.class); + parseTime("-1", MILLISECONDS); + } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/DirCacheCheckoutTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/DirCacheCheckoutTest.java index 5578c03d4a..fbe7dd0417 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/DirCacheCheckoutTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/DirCacheCheckoutTest.java @@ -798,6 +798,7 @@ public class DirCacheCheckoutTest extends RepositoryTestCase { fail("didn't get the expected exception"); } catch (CheckoutConflictException e) { assertConflict("foo"); + assertEquals("foo", e.getConflictingFiles()[0]); assertWorkDir(mkmap("foo", "bar", "other", "other")); assertIndex(mk("other")); } @@ -885,6 +886,7 @@ public class DirCacheCheckoutTest extends RepositoryTestCase { assertWorkDir(mkmap("a", "a", "b/c", "b/c", "d", "d", "e/f", "e/f", "e/g", "e/g3")); assertConflict("e/g"); + assertEquals("e/g", e.getConflictingFiles()[0]); } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RepositoryCacheConfigTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RepositoryCacheConfigTest.java new file mode 100644 index 0000000000..52cc9fb030 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RepositoryCacheConfigTest.java @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2016 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.lib; + +import static org.eclipse.jgit.lib.RepositoryCacheConfig.AUTO_CLEANUP_DELAY; +import static org.eclipse.jgit.lib.RepositoryCacheConfig.NO_CLEANUP; +import static org.junit.Assert.assertEquals; + +import java.util.concurrent.TimeUnit; + +import org.eclipse.jgit.errors.ConfigInvalidException; +import org.junit.Before; +import org.junit.Test; + +public class RepositoryCacheConfigTest { + + private RepositoryCacheConfig config; + + @Before + public void setUp() { + config = new RepositoryCacheConfig(); + } + + @Test + public void testDefaultValues() { + assertEquals(TimeUnit.HOURS.toMillis(1), config.getExpireAfter()); + assertEquals(config.getExpireAfter() / 10, config.getCleanupDelay()); + } + + @Test + public void testCleanupDelay() { + config.setCleanupDelay(TimeUnit.HOURS.toMillis(1)); + assertEquals(TimeUnit.HOURS.toMillis(1), config.getCleanupDelay()); + } + + @Test + public void testAutoCleanupDelay() { + config.setExpireAfter(TimeUnit.MINUTES.toMillis(20)); + config.setCleanupDelay(AUTO_CLEANUP_DELAY); + assertEquals(TimeUnit.MINUTES.toMillis(20), config.getExpireAfter()); + assertEquals(config.getExpireAfter() / 10, config.getCleanupDelay()); + } + + @Test + public void testAutoCleanupDelayShouldBeMax10minutes() { + config.setExpireAfter(TimeUnit.HOURS.toMillis(10)); + assertEquals(TimeUnit.HOURS.toMillis(10), config.getExpireAfter()); + assertEquals(TimeUnit.MINUTES.toMillis(10), config.getCleanupDelay()); + } + + @Test + public void testDisabledCleanupDelay() { + config.setCleanupDelay(NO_CLEANUP); + assertEquals(NO_CLEANUP, config.getCleanupDelay()); + } + + @Test + public void testFromConfig() throws ConfigInvalidException { + Config otherConfig = new Config(); + otherConfig.fromText("[core]\nrepositoryCacheExpireAfter=1000\n" + + "repositoryCacheCleanupDelay=500"); + config.fromConfig(otherConfig); + assertEquals(1000, config.getExpireAfter()); + assertEquals(500, config.getCleanupDelay()); + } +} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RepositoryCacheTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RepositoryCacheTest.java index a1cec2d914..6bea320120 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RepositoryCacheTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RepositoryCacheTest.java @@ -195,17 +195,81 @@ public class RepositoryCacheTest extends RepositoryTestCase { assertEquals(0, ((Repository) db).useCnt.get()); } - public void testRepositoryUnregisteringWhenClosing() throws Exception { + @Test + public void testRepositoryNotUnregisteringWhenClosing() throws Exception { FileKey loc = FileKey.exact(db.getDirectory(), db.getFS()); Repository d2 = RepositoryCache.open(loc); assertEquals(1, d2.useCnt.get()); assertThat(RepositoryCache.getRegisteredKeys(), hasItem(FileKey.exact(db.getDirectory(), db.getFS()))); assertEquals(1, RepositoryCache.getRegisteredKeys().size()); - d2.close(); - assertEquals(0, d2.useCnt.get()); - assertEquals(0, RepositoryCache.getRegisteredKeys().size()); + assertEquals(1, RepositoryCache.getRegisteredKeys().size()); + assertTrue(RepositoryCache.isCached(d2)); + } + + @Test + public void testRepositoryUnregisteringWhenExpired() throws Exception { + Repository repoA = createBareRepository(); + Repository repoB = createBareRepository(); + Repository repoC = createBareRepository(); + RepositoryCache.register(repoA); + RepositoryCache.register(repoB); + RepositoryCache.register(repoC); + + assertEquals(3, RepositoryCache.getRegisteredKeys().size()); + assertTrue(RepositoryCache.isCached(repoA)); + assertTrue(RepositoryCache.isCached(repoB)); + assertTrue(RepositoryCache.isCached(repoC)); + + // fake that repoA was closed more than 1 hour ago (default expiration + // time) + repoA.close(); + repoA.closedAt.set(System.currentTimeMillis() - 65 * 60 * 1000); + // close repoB but this one will not be expired + repoB.close(); + + assertEquals(3, RepositoryCache.getRegisteredKeys().size()); + assertTrue(RepositoryCache.isCached(repoA)); + assertTrue(RepositoryCache.isCached(repoB)); + assertTrue(RepositoryCache.isCached(repoC)); + + RepositoryCache.clearExpired(); + + assertEquals(2, RepositoryCache.getRegisteredKeys().size()); + assertFalse(RepositoryCache.isCached(repoA)); + assertTrue(RepositoryCache.isCached(repoB)); + assertTrue(RepositoryCache.isCached(repoC)); + } + + @Test + public void testReconfigure() throws InterruptedException { + RepositoryCache.register(db); + assertTrue(RepositoryCache.isCached(db)); + db.close(); + assertTrue(RepositoryCache.isCached(db)); + + // Actually, we would only need to validate that + // WorkQueue.getExecutor().scheduleWithFixedDelay is called with proper + // values but since we do not have a mock library, we test + // reconfiguration from a black box perspective. I.e. reconfigure + // expireAfter and cleanupDelay to 1 ms and wait until the Repository + // is evicted to prove that reconfiguration worked. + RepositoryCacheConfig config = new RepositoryCacheConfig(); + config.setExpireAfter(1); + config.setCleanupDelay(1); + config.install(); + + // Instead of using a fixed waiting time, start with small and increase: + // sleep 1, 2, 4, 8, 16, ..., 1024 ms + // This wait will time out after 2048 ms + for (int i = 0; i <= 10; i++) { + Thread.sleep(1 << i); + if (!RepositoryCache.isCached(db)) { + return; + } + } + fail("Repository should have been evicted from cache"); } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/T0001_PersonIdentTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/T0001_PersonIdentTest.java index 1515a07ac4..19181f5ff0 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/T0001_PersonIdentTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/T0001_PersonIdentTest.java @@ -89,12 +89,54 @@ public class T0001_PersonIdentTest { @Test public void testToExternalStringTrimsNameAndEmail() throws Exception { - PersonIdent personIdent = new PersonIdent(" A U Thor ", - " author@example.com "); + PersonIdent personIdent = new PersonIdent(" \u0010A U Thor ", + " author@example.com \u0009"); - String externalString = personIdent.toExternalString(); + assertEquals(" \u0010A U Thor ", personIdent.getName()); + assertEquals(" author@example.com \u0009", personIdent.getEmailAddress()); + String externalString = personIdent.toExternalString(); assertTrue(externalString.startsWith("A U Thor <author@example.com>")); } + @Test + public void testToExternalStringTrimsAllWhitespace() { + String ws = " \u0001 \n "; + PersonIdent personIdent = new PersonIdent(ws, ws); + assertEquals(ws, personIdent.getName()); + assertEquals(ws, personIdent.getEmailAddress()); + + String externalString = personIdent.toExternalString(); + assertTrue(externalString.startsWith(" <>")); + } + + @Test + public void testToExternalStringTrimsOtherBadCharacters() { + String name = " Foo\r\n<Bar> "; + String email = " Baz>\n\u1234<Quux "; + PersonIdent personIdent = new PersonIdent(name, email); + assertEquals(name, personIdent.getName()); + assertEquals(email, personIdent.getEmailAddress()); + + String externalString = personIdent.toExternalString(); + assertTrue(externalString.startsWith("Foo\rBar <Baz\u1234Quux>")); + } + + @Test + public void testEmptyNameAndEmail() { + PersonIdent personIdent = new PersonIdent("", ""); + assertEquals("", personIdent.getName()); + assertEquals("", personIdent.getEmailAddress()); + + String externalString = personIdent.toExternalString(); + assertTrue(externalString.startsWith(" <>")); + } + + @Test + public void testAppendSanitized() { + StringBuilder r = new StringBuilder(); + PersonIdent.appendSanitized(r, " Baz>\n\u1234<Quux "); + assertEquals("Baz\u1234Quux", r.toString()); + } } + diff --git a/org.eclipse.jgit.ui/META-INF/MANIFEST.MF b/org.eclipse.jgit.ui/META-INF/MANIFEST.MF index db339e073c..4d864d6874 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.3.2.qualifier +Bundle-Version: 4.4.2.qualifier Bundle-Vendor: %provider_name Bundle-RequiredExecutionEnvironment: JavaSE-1.7 -Export-Package: org.eclipse.jgit.awtui;version="4.3.2" -Import-Package: org.eclipse.jgit.errors;version="[4.3.2,4.4.0)", - org.eclipse.jgit.lib;version="[4.3.2,4.4.0)", - org.eclipse.jgit.nls;version="[4.3.2,4.4.0)", - org.eclipse.jgit.revplot;version="[4.3.2,4.4.0)", - org.eclipse.jgit.revwalk;version="[4.3.2,4.4.0)", - org.eclipse.jgit.transport;version="[4.3.2,4.4.0)", - org.eclipse.jgit.util;version="[4.3.2,4.4.0)" +Export-Package: org.eclipse.jgit.awtui;version="4.4.2" +Import-Package: org.eclipse.jgit.errors;version="[4.4.2,4.5.0)", + org.eclipse.jgit.lib;version="[4.4.2,4.5.0)", + org.eclipse.jgit.nls;version="[4.4.2,4.5.0)", + org.eclipse.jgit.revplot;version="[4.4.2,4.5.0)", + org.eclipse.jgit.revwalk;version="[4.4.2,4.5.0)", + org.eclipse.jgit.transport;version="[4.4.2,4.5.0)", + org.eclipse.jgit.util;version="[4.4.2,4.5.0)" diff --git a/org.eclipse.jgit.ui/pom.xml b/org.eclipse.jgit.ui/pom.xml index fdd6dad2df..a8d9b5de4a 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.3.2-SNAPSHOT</version> + <version>4.4.2-SNAPSHOT</version> </parent> <artifactId>org.eclipse.jgit.ui</artifactId> diff --git a/org.eclipse.jgit/.settings/.api_filters b/org.eclipse.jgit/.settings/.api_filters index c0dbc779f3..bacfb336a2 100644 --- a/org.eclipse.jgit/.settings/.api_filters +++ b/org.eclipse.jgit/.settings/.api_filters @@ -1,5 +1,13 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <component id="org.eclipse.jgit" version="2"> + <resource path="META-INF/MANIFEST.MF"> + <filter id="924844039"> + <message_arguments> + <message_argument value="4.4.1"/> + <message_argument value="4.4.0"/> + </message_arguments> + </filter> + </resource> <resource path="src/org/eclipse/jgit/attributes/AttributesNode.java" type="org.eclipse.jgit.attributes.AttributesNode"> <filter comment="moved to new AttributesManager" id="338792546"> <message_arguments> diff --git a/org.eclipse.jgit/META-INF/MANIFEST.MF b/org.eclipse.jgit/META-INF/MANIFEST.MF index f94c22c0f5..82b27bf968 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.3.2.qualifier +Bundle-Version: 4.4.2.qualifier Bundle-Localization: plugin Bundle-Vendor: %provider_name Bundle-ActivationPolicy: lazy -Export-Package: org.eclipse.jgit.annotations;version="4.3.2", - org.eclipse.jgit.api;version="4.3.2"; +Export-Package: org.eclipse.jgit.annotations;version="4.4.2", + org.eclipse.jgit.api;version="4.4.2"; uses:="org.eclipse.jgit.revwalk, org.eclipse.jgit.treewalk.filter, org.eclipse.jgit.diff, @@ -21,47 +21,50 @@ Export-Package: org.eclipse.jgit.annotations;version="4.3.2", org.eclipse.jgit.submodule, org.eclipse.jgit.transport, org.eclipse.jgit.merge", - org.eclipse.jgit.api.errors;version="4.3.2";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.errors", - org.eclipse.jgit.attributes;version="4.3.2", - org.eclipse.jgit.blame;version="4.3.2"; + org.eclipse.jgit.api.errors;version="4.4.2";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.errors", + org.eclipse.jgit.attributes;version="4.4.2", + org.eclipse.jgit.blame;version="4.4.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.3.2"; + org.eclipse.jgit.diff;version="4.4.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.3.2"; + org.eclipse.jgit.dircache;version="4.4.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.3.2"; + org.eclipse.jgit.errors;version="4.4.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.3.2";uses:="org.eclipse.jgit.lib", - org.eclipse.jgit.fnmatch;version="4.3.2", - org.eclipse.jgit.gitrepo;version="4.3.2"; + org.eclipse.jgit.events;version="4.4.2";uses:="org.eclipse.jgit.lib", + org.eclipse.jgit.fnmatch;version="4.4.2", + org.eclipse.jgit.gitrepo;version="4.4.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.3.2";x-internal:=true, - org.eclipse.jgit.hooks;version="4.3.2";uses:="org.eclipse.jgit.lib", - org.eclipse.jgit.ignore;version="4.3.2", - org.eclipse.jgit.ignore.internal;version="4.3.2";x-friends:="org.eclipse.jgit.test", - org.eclipse.jgit.internal;version="4.3.2";x-friends:="org.eclipse.jgit.test,org.eclipse.jgit.http.test", - org.eclipse.jgit.internal.ketch;version="4.3.2";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm", - org.eclipse.jgit.internal.storage.dfs;version="4.3.2";x-friends:="org.eclipse.jgit.test,org.eclipse.jgit.http.server", - org.eclipse.jgit.internal.storage.file;version="4.3.2"; + org.eclipse.jgit.gitrepo.internal;version="4.4.2";x-internal:=true, + org.eclipse.jgit.hooks;version="4.4.2";uses:="org.eclipse.jgit.lib", + org.eclipse.jgit.ignore;version="4.4.2", + org.eclipse.jgit.ignore.internal;version="4.4.2";x-friends:="org.eclipse.jgit.test", + org.eclipse.jgit.internal;version="4.4.2";x-friends:="org.eclipse.jgit.test,org.eclipse.jgit.http.test", + org.eclipse.jgit.internal.ketch;version="4.4.2";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm", + org.eclipse.jgit.internal.storage.dfs;version="4.4.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.4.2"; x-friends:="org.eclipse.jgit.test, org.eclipse.jgit.junit, org.eclipse.jgit.junit.http, @@ -69,9 +72,9 @@ Export-Package: org.eclipse.jgit.annotations;version="4.3.2", org.eclipse.jgit.lfs.server, org.eclipse.jgit.pgm, org.eclipse.jgit.pgm.test", - org.eclipse.jgit.internal.storage.pack;version="4.3.2";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm", - org.eclipse.jgit.internal.storage.reftree;version="4.3.2";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm", - org.eclipse.jgit.lib;version="4.3.2"; + org.eclipse.jgit.internal.storage.pack;version="4.4.2";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm", + org.eclipse.jgit.internal.storage.reftree;version="4.4.2";x-friends:="org.eclipse.jgit.junit,org.eclipse.jgit.test,org.eclipse.jgit.pgm", + org.eclipse.jgit.lib;version="4.4.2"; uses:="org.eclipse.jgit.revwalk, org.eclipse.jgit.treewalk.filter, org.eclipse.jgit.util, @@ -81,32 +84,32 @@ Export-Package: org.eclipse.jgit.annotations;version="4.3.2", org.eclipse.jgit.treewalk, org.eclipse.jgit.transport, org.eclipse.jgit.submodule", - org.eclipse.jgit.merge;version="4.3.2"; + org.eclipse.jgit.merge;version="4.4.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.3.2", - org.eclipse.jgit.notes;version="4.3.2"; + org.eclipse.jgit.nls;version="4.4.2", + org.eclipse.jgit.notes;version="4.4.2"; uses:="org.eclipse.jgit.lib, org.eclipse.jgit.treewalk, org.eclipse.jgit.revwalk, org.eclipse.jgit.merge", - org.eclipse.jgit.patch;version="4.3.2";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.diff", - org.eclipse.jgit.revplot;version="4.3.2";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.revwalk", - org.eclipse.jgit.revwalk;version="4.3.2"; + org.eclipse.jgit.patch;version="4.4.2";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.diff", + org.eclipse.jgit.revplot;version="4.4.2";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.revwalk", + org.eclipse.jgit.revwalk;version="4.4.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.3.2";uses:="org.eclipse.jgit.revwalk,org.eclipse.jgit.lib,org.eclipse.jgit.util", - org.eclipse.jgit.storage.file;version="4.3.2";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.util", - org.eclipse.jgit.storage.pack;version="4.3.2";uses:="org.eclipse.jgit.lib", - org.eclipse.jgit.submodule;version="4.3.2";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.treewalk.filter,org.eclipse.jgit.treewalk", - org.eclipse.jgit.transport;version="4.3.2"; + org.eclipse.jgit.revwalk.filter;version="4.4.2";uses:="org.eclipse.jgit.revwalk,org.eclipse.jgit.lib,org.eclipse.jgit.util", + org.eclipse.jgit.storage.file;version="4.4.2";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.util", + org.eclipse.jgit.storage.pack;version="4.4.2";uses:="org.eclipse.jgit.lib", + org.eclipse.jgit.submodule;version="4.4.2";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.treewalk.filter,org.eclipse.jgit.treewalk", + org.eclipse.jgit.transport;version="4.4.2"; uses:="org.eclipse.jgit.transport.resolver, org.eclipse.jgit.revwalk, org.eclipse.jgit.internal.storage.pack, @@ -118,22 +121,22 @@ Export-Package: org.eclipse.jgit.annotations;version="4.3.2", org.eclipse.jgit.transport.http, org.eclipse.jgit.errors, org.eclipse.jgit.storage.pack", - org.eclipse.jgit.transport.http;version="4.3.2";uses:="javax.net.ssl", - org.eclipse.jgit.transport.resolver;version="4.3.2";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.transport", - org.eclipse.jgit.treewalk;version="4.3.2"; + org.eclipse.jgit.transport.http;version="4.4.2";uses:="javax.net.ssl", + org.eclipse.jgit.transport.resolver;version="4.4.2";uses:="org.eclipse.jgit.lib,org.eclipse.jgit.transport", + org.eclipse.jgit.treewalk;version="4.4.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.3.2";uses:="org.eclipse.jgit.treewalk", - org.eclipse.jgit.util;version="4.3.2"; + org.eclipse.jgit.treewalk.filter;version="4.4.2";uses:="org.eclipse.jgit.treewalk", + org.eclipse.jgit.util;version="4.4.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.3.2" + org.eclipse.jgit.util.io;version="4.4.2" Bundle-RequiredExecutionEnvironment: JavaSE-1.7 Require-Bundle: com.jcraft.jsch;bundle-version="[0.1.37,0.2.0)" Import-Package: com.googlecode.javaewah;version="[0.7.9,0.8.0)", diff --git a/org.eclipse.jgit/META-INF/SOURCE-MANIFEST.MF b/org.eclipse.jgit/META-INF/SOURCE-MANIFEST.MF index 3bf02b7772..b0365c749f 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.3.2.qualifier -Eclipse-SourceBundle: org.eclipse.jgit;version="4.3.2.qualifier";roots="." +Bundle-Version: 4.4.2.qualifier +Eclipse-SourceBundle: org.eclipse.jgit;version="4.4.2.qualifier";roots="." diff --git a/org.eclipse.jgit/pom.xml b/org.eclipse.jgit/pom.xml index 40d15c87bb..77bfba1389 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.3.2-SNAPSHOT</version> + <version>4.4.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 992e10bad6..21fbaa4918 100644 --- a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties +++ b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties @@ -21,6 +21,7 @@ atLeastOnePathIsRequired=At least one path is required. atLeastOnePatternIsRequired=At least one pattern is required. atLeastTwoFiltersNeeded=At least two filters needed. atomicPushNotSupported=Atomic push not supported. +atomicRefUpdatesNotSupported=Atomic ref updates not supported authenticationNotSupported=authentication not supported badBase64InputCharacterAt=Bad Base64 input character at {0} : {1} (decimal) badEntryDelimiter=Bad entry delimiter @@ -184,6 +185,7 @@ corruptObjectTruncatedInMode=truncated in mode corruptObjectTruncatedInName=truncated in name corruptObjectTruncatedInObjectId=truncated in object id corruptObjectZeroId=entry points to null SHA-1 +corruptUseCnt=close() called when useCnt is already zero couldNotCheckOutBecauseOfConflicts=Could not check out because of conflicts couldNotDeleteLockFileShouldNotHappen=Could not delete lock file. Should not happen couldNotDeleteTemporaryIndexFileShouldNotHappen=Could not delete temporary index file. Should not happen @@ -313,6 +315,8 @@ indexFileIsTooLargeForJgit=Index file is too large for jgit indexSignatureIsInvalid=Index signature is invalid: {0} indexWriteException=Modified index could not be written initFailedBareRepoDifferentDirs=When initializing a bare repo with directory {0} and separate git-dir {1} specified both folders must point to the same location +initFailedDirIsNoDirectory=Cannot set directory to ''{0}'' which is not a directory +initFailedGitDirIsNoDirectory=Cannot set git-dir to ''{0}'' which is not a directory initFailedNonBareRepoSameDirs=When initializing a non-bare repo with directory {0} and separate git-dir {1} specified both folders should not point to the same location inMemoryBufferLimitExceeded=In-memory buffer limit exceeded inputDidntMatchLength=Input did not match supplied length. {0} bytes are missing. @@ -357,6 +361,8 @@ invalidShallowObject=invalid shallow object {0}, expected commit invalidStageForPath=Invalid stage {0} for path {1} 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} invalidURL=Invalid URL {0} invalidWildcards=Invalid wildcards {0} invalidRefSpec=Invalid refspec {0} @@ -591,6 +597,7 @@ tagNameInvalid=tag name {0} is invalid tagOnRepoWithoutHEADCurrentlyNotSupported=Tag on repository without HEAD currently not supported theFactoryMustNotBeNull=The factory must not be null timerAlreadyTerminated=Timer already terminated +tooManyIncludeRecursions=Too many recursions; circular includes in config file(s)? topologicalSortRequired=Topological sort required. transactionAborted=transaction aborted transportExceptionBadRef=Empty ref: {0}: {1} diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/AddNoteCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/AddNoteCommand.java index 9cf888195e..4235e3786c 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/AddNoteCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/AddNoteCommand.java @@ -87,7 +87,7 @@ public class AddNoteCommand extends GitCommand<Note> { RevCommit notesCommit = null; try (RevWalk walk = new RevWalk(repo); ObjectInserter inserter = repo.newObjectInserter()) { - Ref ref = repo.getRef(notesRef); + Ref ref = repo.findRef(notesRef); // if we have a notes ref, use it if (ref != null) { notesCommit = walk.parseCommit(ref.getObjectId()); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyCommand.java index 8fbf83954c..d74e991395 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ApplyCommand.java @@ -58,6 +58,7 @@ import org.eclipse.jgit.api.errors.PatchFormatException; import org.eclipse.jgit.diff.DiffEntry.ChangeType; import org.eclipse.jgit.diff.RawText; import org.eclipse.jgit.internal.JGitText; +import org.eclipse.jgit.lib.FileMode; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.patch.FileHeader; import org.eclipse.jgit.patch.HunkHeader; @@ -260,6 +261,8 @@ public class ApplyCommand extends GitCommand<ApplyResult> { FileWriter fw = new FileWriter(f); fw.write(sb.toString()); fw.close(); + + getRepository().getFS().setExecute(f, fh.getNewMode() == FileMode.EXECUTABLE_FILE); } private static boolean isChanged(List<String> ol, List<String> nl) { 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 6c80289452..65508eff40 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutCommand.java @@ -223,7 +223,7 @@ public class CheckoutCommand extends GitCommand<Ref> { } } - Ref headRef = repo.getRef(Constants.HEAD); + Ref headRef = repo.exactRef(Constants.HEAD); if (headRef == null) { // TODO Git CLI supports checkout from unborn branch, we should // also allow this @@ -242,7 +242,7 @@ public class CheckoutCommand extends GitCommand<Ref> { JGitText.get().checkoutUnexpectedResult, r.name())); this.status = CheckoutResult.NOT_TRIED_RESULT; - return repo.getRef(Constants.HEAD); + return repo.exactRef(Constants.HEAD); } branch = getStartPointObjectId(); } else { @@ -277,7 +277,7 @@ public class CheckoutCommand extends GitCommand<Ref> { } finally { dc.unlock(); } - Ref ref = repo.getRef(name); + Ref ref = repo.findRef(name); if (ref != null && !ref.getName().startsWith(Constants.R_HEADS)) ref = null; String toName = Repository.shortenRefName(name); @@ -289,7 +289,7 @@ public class CheckoutCommand extends GitCommand<Ref> { updateResult = refUpdate.link(ref.getName()); else if (orphan) { updateResult = refUpdate.link(getBranchName()); - ref = repo.getRef(Constants.HEAD); + ref = repo.exactRef(Constants.HEAD); } else { refUpdate.setNewObjectId(newCommit); updateResult = refUpdate.forceUpdate(); @@ -519,7 +519,7 @@ public class CheckoutCommand extends GitCommand<Ref> { .get().branchNameInvalid, name == null ? "<null>" : name)); //$NON-NLS-1$ if (orphan) { - Ref refToCheck = repo.getRef(getBranchName()); + Ref refToCheck = repo.exactRef(getBranchName()); if (refToCheck != null) throw new RefAlreadyExistsException(MessageFormat.format( JGitText.get().refAlreadyExists, name)); 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 d6e930adac..e82a69798f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CherryPickCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CherryPickCommand.java @@ -126,7 +126,7 @@ public class CherryPickCommand extends GitCommand<CherryPickResult> { try (RevWalk revWalk = new RevWalk(repo)) { // get the head commit - Ref headRef = repo.getRef(Constants.HEAD); + Ref headRef = repo.exactRef(Constants.HEAD); if (headRef == null) throw new NoHeadException( JGitText.get().commitOnRepoWithoutHEADCurrentlyNotSupported); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java index 2ac8729507..ff15fd00c6 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CloneCommand.java @@ -155,6 +155,7 @@ public class CloneCommand extends TransportCommand<CloneCommand, Git> { command.setBare(bare); if (directory == null && gitDir == null) directory = new File(u.getHumanishName(), Constants.DOT_GIT); + validateDirs(directory, gitDir, bare); if (directory != null && directory.exists() && directory.listFiles().length != 0) throw new JGitInternalException(MessageFormat.format( @@ -511,6 +512,15 @@ public class CloneCommand extends TransportCommand<CloneCommand, Git> { private static void validateDirs(File directory, File gitDir, boolean bare) throws IllegalStateException { if (directory != null) { + if (directory.exists() && !directory.isDirectory()) { + throw new IllegalStateException(MessageFormat.format( + JGitText.get().initFailedDirIsNoDirectory, directory)); + } + if (gitDir != null && gitDir.exists() && !gitDir.isDirectory()) { + throw new IllegalStateException(MessageFormat.format( + JGitText.get().initFailedGitDirIsNoDirectory, + gitDir)); + } if (bare) { if (gitDir != null && !gitDir.equals(directory)) throw new IllegalStateException(MessageFormat.format( diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java index 0abb8ba4ec..561319c44a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java @@ -124,6 +124,8 @@ public class CommitCommand extends GitCommand<RevCommit> { private String reflogComment; + private boolean useDefaultReflogMessage = true; + /** * Setting this option bypasses the pre-commit and commit-msg hooks. */ @@ -193,7 +195,7 @@ public class CommitCommand extends GitCommand<RevCommit> { } } - Ref head = repo.getRef(Constants.HEAD); + Ref head = repo.exactRef(Constants.HEAD); if (head == null) throw new NoHeadException( JGitText.get().commitOnRepoWithoutHEADCurrentlyNotSupported); @@ -258,7 +260,7 @@ public class CommitCommand extends GitCommand<RevCommit> { RevCommit revCommit = rw.parseCommit(commitId); RefUpdate ru = repo.updateRef(Constants.HEAD); ru.setNewObjectId(commitId); - if (reflogComment != null) { + if (!useDefaultReflogMessage) { ru.setRefLogMessage(reflogComment, false); } else { String prefix = amend ? "commit (amend): " //$NON-NLS-1$ @@ -790,10 +792,13 @@ public class CommitCommand extends GitCommand<RevCommit> { * Override the message written to the reflog * * @param reflogComment + * the comment to be written into the reflog or <code>null</code> + * to specify that no reflog should be written * @return {@code this} */ public CommitCommand setReflogComment(String reflogComment) { this.reflogComment = reflogComment; + useDefaultReflogMessage = false; return this; } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CreateBranchCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CreateBranchCommand.java index a6646602e9..69d82bcc67 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CreateBranchCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CreateBranchCommand.java @@ -125,7 +125,7 @@ public class CreateBranchCommand extends GitCommand<Ref> { checkCallable(); processOptions(); try (RevWalk revWalk = new RevWalk(repo)) { - Ref refToCheck = repo.getRef(name); + Ref refToCheck = repo.findRef(name); boolean exists = refToCheck != null && refToCheck.getName().startsWith(Constants.R_HEADS); if (!force && exists) @@ -135,7 +135,7 @@ public class CreateBranchCommand extends GitCommand<Ref> { ObjectId startAt = getStartPointObjectId(); String startPointFullName = null; if (startPoint != null) { - Ref baseRef = repo.getRef(startPoint); + Ref baseRef = repo.findRef(startPoint); if (baseRef != null) startPointFullName = baseRef.getName(); } @@ -207,7 +207,7 @@ public class CreateBranchCommand extends GitCommand<Ref> { .get().createBranchUnexpectedResult, updateResult .name())); - Ref result = repo.getRef(name); + Ref result = repo.findRef(name); if (result == null) throw new JGitInternalException( JGitText.get().createBranchFailedUnknownReason); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/DeleteBranchCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/DeleteBranchCommand.java index 61beb2f0d0..ecc1ce5a70 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/DeleteBranchCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/DeleteBranchCommand.java @@ -114,7 +114,7 @@ public class DeleteBranchCommand extends GitCommand<List<String>> { for (String branchName : branchNames) { if (branchName == null) continue; - Ref currentRef = repo.getRef(branchName); + Ref currentRef = repo.findRef(branchName); if (currentRef == null) continue; @@ -130,7 +130,7 @@ public class DeleteBranchCommand extends GitCommand<List<String>> { for (String branchName : branchNames) { if (branchName == null) continue; - Ref currentRef = repo.getRef(branchName); + Ref currentRef = repo.findRef(branchName); if (currentRef == null) continue; String fullName = currentRef.getName(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/DeleteTagCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/DeleteTagCommand.java index ae511c6df0..3aeec48d9d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/DeleteTagCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/DeleteTagCommand.java @@ -90,7 +90,7 @@ public class DeleteTagCommand extends GitCommand<List<String>> { for (String tagName : tags) { if (tagName == null) continue; - Ref currentRef = repo.getRef(tagName); + Ref currentRef = repo.findRef(tagName); if (currentRef == null) continue; String fullName = currentRef.getName(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/ListBranchCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/ListBranchCommand.java index 904c74f6de..efcfd16823 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ListBranchCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ListBranchCommand.java @@ -108,7 +108,7 @@ public class ListBranchCommand extends GitCommand<List<Ref>> { Collection<Ref> refs = new ArrayList<Ref>(); // Also return HEAD if it's detached - Ref head = repo.getRef(Constants.HEAD); + Ref head = repo.exactRef(Constants.HEAD); if (head != null && head.getLeaf().getName().equals(Constants.HEAD)) refs.add(head); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/ListNotesCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/ListNotesCommand.java index 796ac798f0..ff963ede89 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ListNotesCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ListNotesCommand.java @@ -82,7 +82,7 @@ public class ListNotesCommand extends GitCommand<List<Note>> { List<Note> notes = new ArrayList<Note>(); NoteMap map = NoteMap.newEmptyMap(); try (RevWalk walk = new RevWalk(repo)) { - Ref ref = repo.getRef(notesRef); + Ref ref = repo.findRef(notesRef); // if we have a notes ref, use it if (ref != null) { RevCommit notesCommit = walk.parseCommit(ref.getObjectId()); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/LogCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/LogCommand.java index 9690f799c1..bb1a738149 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/LogCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/LogCommand.java @@ -65,6 +65,7 @@ import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevWalk; import org.eclipse.jgit.revwalk.filter.AndRevFilter; import org.eclipse.jgit.revwalk.filter.MaxCountRevFilter; +import org.eclipse.jgit.revwalk.filter.RevFilter; import org.eclipse.jgit.revwalk.filter.SkipRevFilter; import org.eclipse.jgit.treewalk.filter.AndTreeFilter; import org.eclipse.jgit.treewalk.filter.PathFilter; @@ -104,6 +105,8 @@ public class LogCommand extends GitCommand<Iterable<RevCommit>> { private boolean startSpecified = false; + private RevFilter revFilter; + private final List<PathFilter> pathFilters = new ArrayList<PathFilter>(); private int maxCount = -1; @@ -156,6 +159,11 @@ public class LogCommand extends GitCommand<Iterable<RevCommit>> { e); } } + + if (this.revFilter != null) { + walk.setRevFilter(this.revFilter); + } + setCallable(false); return walk; } @@ -342,4 +350,21 @@ public class LogCommand extends GitCommand<Iterable<RevCommit>> { , start), e); } } + + + /** + * Sets a filter for the <code>LogCommand</code>. + * + * + * @param aFilter + * the filter that this instance of <code>LogCommand</code> + * should use + * @return {@code this} + * @since 4.4 + */ + public LogCommand setRevFilter(RevFilter aFilter) { + checkCallable(); + this.revFilter = aFilter; + return this; + } } 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 bfe90a3a4f..38b10971f4 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/MergeCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/MergeCommand.java @@ -231,7 +231,7 @@ public class MergeCommand extends GitCommand<MergeResult> { RevWalk revWalk = null; DirCacheCheckout dco = null; try { - Ref head = repo.getRef(Constants.HEAD); + Ref head = repo.exactRef(Constants.HEAD); if (head == null) throw new NoHeadException( JGitText.get().commitOnRepoWithoutHEADCurrentlyNotSupported); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/PushCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/PushCommand.java index f5b82bdd7d..0a49f78069 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/PushCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/PushCommand.java @@ -55,6 +55,7 @@ import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.api.errors.InvalidRemoteException; import org.eclipse.jgit.api.errors.JGitInternalException; import org.eclipse.jgit.errors.NotSupportedException; +import org.eclipse.jgit.errors.TooLargeObjectInPackException; import org.eclipse.jgit.errors.TooLargePackException; import org.eclipse.jgit.errors.TransportException; import org.eclipse.jgit.internal.JGitText; @@ -130,7 +131,7 @@ public class PushCommand extends refSpecs.addAll(config.getPushRefSpecs()); } if (refSpecs.isEmpty()) { - Ref head = repo.getRef(Constants.HEAD); + Ref head = repo.exactRef(Constants.HEAD); if (head != null && head.isSymbolic()) refSpecs.add(new RefSpec(head.getLeaf().getName())); } @@ -160,6 +161,9 @@ public class PushCommand extends } catch (TooLargePackException e) { throw new org.eclipse.jgit.api.errors.TooLargePackException( e.getMessage(), e); + } catch (TooLargeObjectInPackException e) { + throw new org.eclipse.jgit.api.errors.TooLargeObjectInPackException( + e.getMessage(), e); } catch (TransportException e) { throw new org.eclipse.jgit.api.errors.TransportException( e.getMessage(), e); @@ -344,7 +348,7 @@ public class PushCommand extends } else { Ref src; try { - src = repo.getRef(nameOrSpec); + src = repo.findRef(nameOrSpec); } catch (IOException e) { throw new JGitInternalException( JGitText.get().exceptionCaughtDuringExecutionOfPushCommand, 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 643ec7a51f..2d6a76b390 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java @@ -419,7 +419,7 @@ public class RebaseCommand extends GitCommand<RebaseResult> { private void updateStashRef(ObjectId commitId, PersonIdent refLogIdent, String refLogMessage) throws IOException { - Ref currentRef = repo.getRef(Constants.R_STASH); + Ref currentRef = repo.exactRef(Constants.R_STASH); RefUpdate refUpdate = repo.updateRef(Constants.R_STASH); refUpdate.setNewObjectId(commitId); refUpdate.setRefLogIdent(refLogIdent); @@ -750,7 +750,7 @@ public class RebaseCommand extends GitCommand<RebaseResult> { private void resetSoftToParent() throws IOException, GitAPIException, CheckoutConflictException { - Ref ref = repo.getRef(Constants.ORIG_HEAD); + Ref ref = repo.exactRef(Constants.ORIG_HEAD); ObjectId orig_head = ref == null ? null : ref.getObjectId(); try { // we have already commited the cherry-picked commit. @@ -1207,7 +1207,7 @@ public class RebaseCommand extends GitCommand<RebaseResult> { } private Ref getHead() throws IOException, RefNotFoundException { - Ref head = repo.getRef(Constants.HEAD); + Ref head = repo.exactRef(Constants.HEAD); if (head == null || head.getObjectId() == null) throw new RefNotFoundException(MessageFormat.format( JGitText.get().refNotResolved, Constants.HEAD)); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/RemoveNoteCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/RemoveNoteCommand.java index a526c27531..1c4880c1e1 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/RemoveNoteCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/RemoveNoteCommand.java @@ -85,7 +85,7 @@ public class RemoveNoteCommand extends GitCommand<Note> { ObjectInserter inserter = repo.newObjectInserter()) { NoteMap map = NoteMap.newEmptyMap(); RevCommit notesCommit = null; - Ref ref = repo.getRef(notesRef); + Ref ref = repo.exactRef(notesRef); // if we have a notes ref, use it if (ref != null) { notesCommit = walk.parseCommit(ref.getObjectId()); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/RenameBranchCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/RenameBranchCommand.java index 0731dd45ec..044a48611b 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/RenameBranchCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/RenameBranchCommand.java @@ -107,11 +107,11 @@ public class RenameBranchCommand extends GitCommand<Ref> { try { String fullOldName; String fullNewName; - if (repo.getRef(newName) != null) + if (repo.findRef(newName) != null) throw new RefAlreadyExistsException(MessageFormat.format( JGitText.get().refAlreadyExists1, newName)); if (oldName != null) { - Ref ref = repo.getRef(oldName); + Ref ref = repo.findRef(oldName); if (ref == null) throw new RefNotFoundException(MessageFormat.format( JGitText.get().refNotResolved, oldName)); @@ -186,7 +186,7 @@ public class RenameBranchCommand extends GitCommand<Ref> { repoConfig.save(); } - Ref resultRef = repo.getRef(newName); + Ref resultRef = repo.findRef(newName); if (resultRef == null) throw new JGitInternalException( JGitText.get().renameBranchFailedUnknownReason); 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 4c91e6c17f..e385a5d174 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ResetCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ResetCommand.java @@ -171,7 +171,7 @@ public class ResetCommand extends GitCommand<Ref> { // reset [commit] -- paths resetIndexForPaths(commitTree); setCallable(false); - return repo.getRef(Constants.HEAD); + return repo.exactRef(Constants.HEAD); } final Ref result; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/RevertCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/RevertCommand.java index 8015773624..9d79ed0299 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/RevertCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/RevertCommand.java @@ -129,7 +129,7 @@ public class RevertCommand extends GitCommand<RevCommit> { try (RevWalk revWalk = new RevWalk(repo)) { // get the head commit - Ref headRef = repo.getRef(Constants.HEAD); + Ref headRef = repo.exactRef(Constants.HEAD); if (headRef == null) throw new NoHeadException( JGitText.get().commitOnRepoWithoutHEADCurrentlyNotSupported); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/ShowNoteCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/ShowNoteCommand.java index 82db88190f..168ea51e77 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/ShowNoteCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/ShowNoteCommand.java @@ -79,7 +79,7 @@ public class ShowNoteCommand extends GitCommand<Note> { NoteMap map = NoteMap.newEmptyMap(); RevCommit notesCommit = null; try (RevWalk walk = new RevWalk(repo)) { - Ref ref = repo.getRef(notesRef); + Ref ref = repo.exactRef(notesRef); // if we have a notes ref, use it if (ref != null) { notesCommit = walk.parseCommit(ref.getObjectId()); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/StashApplyCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/StashApplyCommand.java index 1699b9f3d7..b8ee1ec0b3 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/StashApplyCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/StashApplyCommand.java @@ -223,8 +223,13 @@ public class StashApplyCommand extends GitCommand<ObjectId> { ResolveMerger untrackedMerger = (ResolveMerger) strategy .newMerger(repo, true); untrackedMerger.setCommitNames(new String[] { - "stashed HEAD", "HEAD", "untracked files" }); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ - untrackedMerger.setBase(stashHeadCommit); + "null", "HEAD", "untracked files" }); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ + // There is no common base for HEAD & untracked files + // because the commit for untracked files has no parent. If + // we use stashHeadCommit as common base (as in the other + // merges) we potentially report conflicts for files + // which are not even member of untracked files commit + untrackedMerger.setBase(null); boolean ok = untrackedMerger.merge(headCommit, untrackedCommit); if (ok) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/StashCreateCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/StashCreateCommand.java index ef32ac929a..ee9b7fcf72 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/StashCreateCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/StashCreateCommand.java @@ -206,7 +206,7 @@ public class StashCreateCommand extends GitCommand<RevCommit> { String refLogMessage) throws IOException { if (ref == null) return; - Ref currentRef = repo.getRef(ref); + Ref currentRef = repo.findRef(ref); RefUpdate refUpdate = repo.updateRef(ref); refUpdate.setNewObjectId(commitId); refUpdate.setRefLogIdent(refLogIdent); @@ -220,7 +220,7 @@ public class StashCreateCommand extends GitCommand<RevCommit> { private Ref getHead() throws GitAPIException { try { - Ref head = repo.getRef(Constants.HEAD); + Ref head = repo.exactRef(Constants.HEAD); if (head == null || head.getObjectId() == null) throw new NoHeadException(JGitText.get().headRequiredToStash); return head; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/StashDropCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/StashDropCommand.java index f6903be05c..6e1d0f2703 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/StashDropCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/StashDropCommand.java @@ -118,7 +118,7 @@ public class StashDropCommand extends GitCommand<ObjectId> { private Ref getRef() throws GitAPIException { try { - return repo.getRef(R_STASH); + return repo.exactRef(R_STASH); } catch (IOException e) { throw new InvalidRefNameException(MessageFormat.format( JGitText.get().cannotRead, R_STASH), e); @@ -236,7 +236,7 @@ public class StashDropCommand extends GitCommand<ObjectId> { updateRef(stashRef, entryId); try { - Ref newStashRef = repo.getRef(R_STASH); + Ref newStashRef = repo.exactRef(R_STASH); return newStashRef != null ? newStashRef.getObjectId() : null; } catch (IOException e) { throw new InvalidRefNameException(MessageFormat.format( diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/StashListCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/StashListCommand.java index 59a83aae3f..aedc9a6e12 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/StashListCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/StashListCommand.java @@ -81,7 +81,7 @@ public class StashListCommand extends GitCommand<Collection<RevCommit>> { checkCallable(); try { - if (repo.getRef(Constants.R_STASH) == null) + if (repo.exactRef(Constants.R_STASH) == null) return Collections.emptyList(); } catch (IOException e) { throw new InvalidRefNameException(MessageFormat.format( 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 e7fe71a890..024f0bebde 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleSyncCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/SubmoduleSyncCommand.java @@ -101,7 +101,7 @@ public class SubmoduleSyncCommand extends GitCommand<Map<String, String>> { * @throws IOException */ protected String getHeadBranch(final Repository subRepo) throws IOException { - Ref head = subRepo.getRef(Constants.HEAD); + Ref head = subRepo.exactRef(Constants.HEAD); if (head != null && head.isSymbolic()) return Repository.shortenRefName(head.getLeaf().getName()); else diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/TagCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/TagCommand.java index ca98cedfd8..39dd42cc51 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/TagCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/TagCommand.java @@ -184,7 +184,7 @@ public class TagCommand extends GitCommand<Ref> { switch (updateResult) { case NEW: case FORCED: - return repo.getRef(refName); + return repo.exactRef(refName); case LOCK_FAILURE: throw new ConcurrentRefUpdateException( JGitText.get().couldNotLockHEAD, tagRef.getRef(), diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/errors/TooLargeObjectInPackException.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/errors/TooLargeObjectInPackException.java new file mode 100644 index 0000000000..08c25c28ed --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/errors/TooLargeObjectInPackException.java @@ -0,0 +1,65 @@ +/* + * 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.api.errors; + +/** + * Exception thrown when the server rejected a too large pack + * + * @since 4.4 + */ +public class TooLargeObjectInPackException extends TransportException { + private static final long serialVersionUID = 1L; + + /** + * @param msg + * message describing the transport failure. + */ + public TooLargeObjectInPackException(String msg) { + super(msg); + } + + /** + * @param msg + * message describing the transport exception. + * @param cause + * why the transport failed. + */ + public TooLargeObjectInPackException(String msg, Throwable cause) { + super(msg, cause); + } +} 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 fc4cc90937..12ceb74abb 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java @@ -354,8 +354,16 @@ public class DirCacheCheckout { // The index entry is missing if (f != null && !FileMode.TREE.equals(f.getEntryFileMode()) && !f.isEntryIgnored()) { - // don't overwrite an untracked and not ignored file - conflicts.add(walk.getPathString()); + if (failOnConflict) { + // don't overwrite an untracked and not ignored file + conflicts.add(walk.getPathString()); + } else { + // failOnConflict is false. Putting something to conflicts + // would mean we delete it. Instead we want the mergeCommit + // content to be checked out. + update(m.getEntryPathString(), m.getEntryObjectId(), + m.getEntryFileMode()); + } } else update(m.getEntryPathString(), m.getEntryObjectId(), m.getEntryFileMode()); @@ -390,6 +398,9 @@ public class DirCacheCheckout { if (f != null) { // There is a file/folder for that path in the working tree if (walk.isDirectoryFileConflict()) { + // We put it in conflicts. Even if failOnConflict is false + // this would cause the path to be deleted. Thats exactly what + // we want in this situation conflicts.add(walk.getPathString()); } else { // No file/folder conflict exists. All entries are files or diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/errors/CheckoutConflictException.java b/org.eclipse.jgit/src/org/eclipse/jgit/errors/CheckoutConflictException.java index db29f3f15b..b6010b6983 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/errors/CheckoutConflictException.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/errors/CheckoutConflictException.java @@ -56,6 +56,8 @@ import org.eclipse.jgit.internal.JGitText; public class CheckoutConflictException extends IOException { private static final long serialVersionUID = 1L; + private final String[] conflicting; + /** * Construct a CheckoutConflictException for the specified file * @@ -63,6 +65,7 @@ public class CheckoutConflictException extends IOException { */ public CheckoutConflictException(String file) { super(MessageFormat.format(JGitText.get().checkoutConflictWithFile, file)); + conflicting = new String[] { file }; } /** @@ -72,6 +75,16 @@ public class CheckoutConflictException extends IOException { */ public CheckoutConflictException(String[] files) { super(MessageFormat.format(JGitText.get().checkoutConflictWithFiles, buildList(files))); + conflicting = files; + } + + /** + * @return the relative paths of the conflicting files (relative to the + * working directory root). + * @since 4.4 + */ + public String[] getConflictingFiles() { + return conflicting; } private static String buildList(String[] files) { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/errors/TooLargeObjectInPackException.java b/org.eclipse.jgit/src/org/eclipse/jgit/errors/TooLargeObjectInPackException.java index 79515fcd7c..b5b1af542e 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/errors/TooLargeObjectInPackException.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/errors/TooLargeObjectInPackException.java @@ -43,13 +43,13 @@ package org.eclipse.jgit.errors; -import java.io.IOException; import java.text.MessageFormat; import org.eclipse.jgit.internal.JGitText; +import org.eclipse.jgit.transport.URIish; /** Thrown when PackParser finds an object larger than a predefined limit */ -public class TooLargeObjectInPackException extends IOException { +public class TooLargeObjectInPackException extends TransportException { private static final long serialVersionUID = 1L; /** @@ -79,4 +79,17 @@ public class TooLargeObjectInPackException extends IOException { super(MessageFormat.format(JGitText.get().receivePackObjectTooLarge2, Long.valueOf(objectSize), Long.valueOf(maxObjectSizeLimit))); } + + /** + * Construct a too large object in pack exception. + * + * @param uri + * URI used for transport + * @param s + * message + * @since 4.4 + */ + public TooLargeObjectInPackException(URIish uri, String s) { + super(uri.setPass(null) + ": " + s); //$NON-NLS-1$ + } }
\ No newline at end of file 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 796b422bb2..2370ae14c7 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/ManifestParser.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/ManifestParser.java @@ -192,6 +192,8 @@ public class ManifestParser extends DefaultHandler { attributes.getValue("revision"), //$NON-NLS-1$ attributes.getValue("remote"), //$NON-NLS-1$ attributes.getValue("groups")); //$NON-NLS-1$ + currentProject.setRecommendShallow( + attributes.getValue("clone-depth")); //$NON-NLS-1$ } else if ("remote".equals(qName)) { //$NON-NLS-1$ String alias = attributes.getValue("alias"); //$NON-NLS-1$ String fetch = attributes.getValue("fetch"); //$NON-NLS-1$ 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 ee937f585b..ca976a1a3a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java @@ -53,6 +53,7 @@ import java.text.MessageFormat; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Set; import org.eclipse.jgit.annotations.Nullable; import org.eclipse.jgit.api.Git; @@ -110,6 +111,8 @@ public class RepoCommand extends GitCommand<RevCommit> { private String branch; private String targetBranch = Constants.HEAD; private boolean recordRemoteBranch = false; + private boolean recordSubmoduleLabels = false; + private boolean recordShallowSubmodules = false; private PersonIdent author; private RemoteReader callback; private InputStream inputStream; @@ -345,6 +348,36 @@ public class RepoCommand extends GitCommand<RevCommit> { } /** + * Set whether the labels field should be recorded as a label in + * .gitattributes. + * <p> + * Not implemented for non-bare repositories. + * + * @param enable Whether to record the labels in the .gitattributes + * @return this command + * @since 4.4 + */ + public RepoCommand setRecordSubmoduleLabels(boolean enable) { + this.recordSubmoduleLabels = enable; + return this; + } + + /** + * Set whether the clone-depth field should be recorded as a shallow + * recommendation in .gitmodules. + * <p> + * Not implemented for non-bare repositories. + * + * @param enable Whether to record the shallow recommendation. + * @return this command + * @since 4.4 + */ + public RepoCommand setRecommendShallow(boolean enable) { + this.recordShallowSubmodules = enable; + return this; + } + + /** * The progress monitor associated with the clone operation. By default, * this is set to <code>NullProgressMonitor</code> * @@ -452,7 +485,9 @@ public class RepoCommand extends GitCommand<RevCommit> { addSubmodule(proj.getUrl(), proj.getPath(), proj.getRevision(), - proj.getCopyFiles()); + proj.getCopyFiles(), + proj.getGroups(), + proj.getRecommendShallow()); } } catch (GitAPIException | IOException e) { throw new ManifestErrorException(e); @@ -472,6 +507,7 @@ public class RepoCommand extends GitCommand<RevCommit> { ObjectInserter inserter = repo.newObjectInserter(); try (RevWalk rw = new RevWalk(repo)) { Config cfg = new Config(); + StringBuilder attributes = new StringBuilder(); for (RepoProject proj : bareProjects) { String name = proj.getPath(); String nameUri = proj.getName(); @@ -492,6 +528,27 @@ public class RepoCommand extends GitCommand<RevCommit> { cfg.setString("submodule", name, "branch", //$NON-NLS-1$ //$NON-NLS-2$ proj.getRevision()); } + + if (recordShallowSubmodules && proj.getRecommendShallow() != null) { + // The shallow recommendation is losing information. + // As the repo manifests stores the recommended + // depth in the 'clone-depth' field, while + // git core only uses a binary 'shallow = true/false' + // hint, we'll map any depth to 'shallow = true' + cfg.setBoolean("submodule", name, "shallow", //$NON-NLS-1$ //$NON-NLS-2$ + true); + } + } + if (recordSubmoduleLabels) { + StringBuilder rec = new StringBuilder(); + rec.append("/"); //$NON-NLS-1$ + rec.append(name); + for (String group : proj.getGroups()) { + rec.append(" "); //$NON-NLS-1$ + rec.append(group); + } + rec.append("\n"); //$NON-NLS-1$ + attributes.append(rec.toString()); } cfg.setString("submodule", name, "path", name); //$NON-NLS-1$ //$NON-NLS-2$ cfg.setString("submodule", name, "url", nameUri); //$NON-NLS-1$ //$NON-NLS-2$ @@ -522,6 +579,16 @@ public class RepoCommand extends GitCommand<RevCommit> { dcEntry.setFileMode(FileMode.REGULAR_FILE); builder.add(dcEntry); + if (recordSubmoduleLabels) { + // create a new DirCacheEntry for .gitattributes file. + final DirCacheEntry dcEntryAttr = new DirCacheEntry(Constants.DOT_GIT_ATTRIBUTES); + ObjectId attrId = inserter.insert(Constants.OBJ_BLOB, + attributes.toString().getBytes(Constants.CHARACTER_ENCODING)); + dcEntryAttr.setObjectId(attrId); + dcEntryAttr.setFileMode(FileMode.REGULAR_FILE); + builder.add(dcEntryAttr); + } + builder.finish(); ObjectId treeId = index.writeTree(inserter); @@ -575,9 +642,10 @@ public class RepoCommand extends GitCommand<RevCommit> { } private void addSubmodule(String url, String name, String revision, - List<CopyFile> copyfiles) throws GitAPIException, IOException { + List<CopyFile> copyfiles, Set<String> groups, String recommendShallow) + throws GitAPIException, IOException { if (repo.isBare()) { - RepoProject proj = new RepoProject(url, name, revision, null, null); + RepoProject proj = new RepoProject(url, name, revision, null, groups, recommendShallow); proj.addCopyFiles(copyfiles); bareProjects.add(proj); } else { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoProject.java b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoProject.java index f6d1209cb5..d29f6c01e2 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoProject.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoProject.java @@ -70,6 +70,7 @@ public class RepoProject implements Comparable<RepoProject> { private final String remote; private final Set<String> groups; private final List<CopyFile> copyfiles; + private String recommendShallow; private String url; private String defaultRevision; @@ -134,10 +135,14 @@ public class RepoProject implements Comparable<RepoProject> { * @param remote * name of the remote definition * @param groups - * comma separated group list + * set of groups + * @param recommendShallow + * recommendation for shallowness + * @since 4.4 */ public RepoProject(String name, String path, String revision, - String remote, String groups) { + String remote, Set<String> groups, + String recommendShallow) { if (name == null) { throw new NullPointerException(); } @@ -148,13 +153,31 @@ public class RepoProject implements Comparable<RepoProject> { this.path = name; this.revision = revision; this.remote = remote; - this.groups = new HashSet<String>(); - if (groups != null && groups.length() > 0) - this.groups.addAll(Arrays.asList(groups.split(","))); //$NON-NLS-1$ + this.groups = groups; + this.recommendShallow = recommendShallow; copyfiles = new ArrayList<CopyFile>(); } /** + * @param name + * the relative path to the {@code remote} + * @param path + * the relative path to the super project + * @param revision + * a SHA-1 or branch name or tag name + * @param remote + * name of the remote definition + * @param groups + * comma separated group list + */ + public RepoProject(String name, String path, String revision, + String remote, String groups) { + this(name, path, revision, remote, new HashSet<String>(), null); + if (groups != null && groups.length() > 0) + this.setGroups(groups); + } + + /** * Set the url of the sub repo. * * @param url @@ -166,6 +189,20 @@ public class RepoProject implements Comparable<RepoProject> { } /** + * Set the url of the sub repo. + * + * @param groups + * comma separated group list + * @return this for chaining. + * @since 4.4 + */ + public RepoProject setGroups(String groups) { + this.groups.clear(); + this.groups.addAll(Arrays.asList(groups.split(","))); //$NON-NLS-1$ + return this; + } + + /** * Set the default revision for the sub repo. * * @param defaultRevision @@ -241,6 +278,37 @@ public class RepoProject implements Comparable<RepoProject> { } /** + * Return the set of groups. + * + * @return a Set of groups. + * @since 4.4 + */ + public Set<String> getGroups() { + return groups; + } + + /** + * Return the recommendation for shallowness. + * + * @return the String of "clone-depth" + * @since 4.4 + */ + public String getRecommendShallow() { + return recommendShallow; + } + + /** + * Sets the recommendation for shallowness. + * + * @param recommendShallow + * recommendation for shallowness + * @since 4.4 + */ + public void setRecommendShallow(String recommendShallow) { + this.recommendShallow = recommendShallow; + } + + /** * Add a copy file configuration. * * @param copyfile 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 7740a2bb80..b7ef0854c9 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java @@ -80,6 +80,7 @@ public class JGitText extends TranslationBundle { /***/ public String atLeastOnePatternIsRequired; /***/ public String atLeastTwoFiltersNeeded; /***/ public String atomicPushNotSupported; + /***/ public String atomicRefUpdatesNotSupported; /***/ public String authenticationNotSupported; /***/ public String badBase64InputCharacterAt; /***/ public String badEntryDelimiter; @@ -244,6 +245,7 @@ public class JGitText extends TranslationBundle { /***/ public String corruptObjectTruncatedInObjectId; /***/ public String corruptObjectZeroId; /***/ public String corruptPack; + /***/ public String corruptUseCnt; /***/ public String couldNotCheckOutBecauseOfConflicts; /***/ public String couldNotDeleteLockFileShouldNotHappen; /***/ public String couldNotDeleteTemporaryIndexFileShouldNotHappen; @@ -372,6 +374,8 @@ public class JGitText extends TranslationBundle { /***/ public String indexSignatureIsInvalid; /***/ public String indexWriteException; /***/ public String initFailedBareRepoDifferentDirs; + /***/ public String initFailedDirIsNoDirectory; + /***/ public String initFailedGitDirIsNoDirectory; /***/ public String initFailedNonBareRepoSameDirs; /***/ public String inMemoryBufferLimitExceeded; /***/ public String inputDidntMatchLength; @@ -415,6 +419,8 @@ public class JGitText extends TranslationBundle { /***/ public String invalidStageForPath; /***/ public String invalidTagOption; /***/ public String invalidTimeout; + /***/ public String invalidTimeUnitValue2; + /***/ public String invalidTimeUnitValue3; /***/ public String invalidURL; /***/ public String invalidWildcards; /***/ public String invalidRefSpec; @@ -651,6 +657,7 @@ public class JGitText extends TranslationBundle { /***/ public String transactionAborted; /***/ public String theFactoryMustNotBeNull; /***/ public String timerAlreadyTerminated; + /***/ public String tooManyIncludeRecursions; /***/ public String topologicalSortRequired; /***/ public String transportExceptionBadRef; /***/ public String transportExceptionEmptyRef; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollector.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollector.java index 33be3b15a8..dc91a70866 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollector.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollector.java @@ -241,7 +241,12 @@ public class DfsGarbageCollector { if (!addl.isEmpty()) { List<Ref> all = new ArrayList<>(refs.size() + addl.size()); all.addAll(refs); - all.addAll(addl); + // add additional refs which start with refs/ + for (Ref r : addl) { + if (r.getName().startsWith(Constants.R_REFS)) { + all.add(r); + } + } return all; } return refs; 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 e5ae9800fa..f5673e83d1 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 @@ -601,6 +601,11 @@ public class DfsInserter extends ObjectInserter { } @Override + public ObjectInserter getCreatedFromInserter() { + return DfsInserter.this; + } + + @Override public void close() { ctx.close(); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackFile.java index 96f1d542ca..4eabb03163 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackFile.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackFile.java @@ -1189,7 +1189,7 @@ public final class DfsPackFile { } } - private boolean isCorrupt(long offset) { + boolean isCorrupt(long offset) { LongList list = corruptObjects; if (list == null) return false; 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 1665c2c772..66421e2a88 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 @@ -476,7 +476,7 @@ public final class DfsReader extends ObjectReader implements ObjectReuseAsIs { PackIndex idx = pack.getPackIndex(this); for (ObjectToPack otp : objects) { long p = idx.findOffset(otp); - if (0 < p) { + if (0 < p && !pack.isCorrupt(p)) { otp.setOffset(p); tmp.add((DfsObjectToPack) otp); } 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 b312835bb3..de18eadb22 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 @@ -252,11 +252,20 @@ public class InMemoryRepository extends DfsRepository { } } - private class MemRefDatabase extends DfsRefDatabase { + /** + * A ref database storing all refs in-memory. + * <p> + * This class is protected (and not private) to facilitate testing using + * subclasses of InMemoryRepository. + */ + protected class MemRefDatabase extends DfsRefDatabase { private final ConcurrentMap<String, Ref> refs = new ConcurrentHashMap<String, Ref>(); private final ReadWriteLock lock = new ReentrantReadWriteLock(true /* fair */); - MemRefDatabase() { + /** + * Initialize a new in-memory ref database. + */ + protected MemRefDatabase() { super(InMemoryRepository.this); } @@ -271,7 +280,7 @@ public class InMemoryRepository extends DfsRepository { @Override public void execute(RevWalk walk, ProgressMonitor monitor) throws IOException { - if (performsAtomicTransactions()) { + if (performsAtomicTransactions() && isAtomic()) { try { lock.writeLock().lock(); batch(getCommands()); 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 b02efedea3..53fd37e534 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 @@ -491,7 +491,7 @@ public class FileRepository extends Repository { * @throws IOException the ref could not be accessed. */ public ReflogReader getReflogReader(String refName) throws IOException { - Ref ref = getRef(refName); + Ref ref = findRef(refName); if (ref != null) return new ReflogReaderImpl(this, ref.getName()); return null; 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 9cdb753221..c998ebe960 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 @@ -655,8 +655,12 @@ public class GC { } /** - * Returns a collection of all refs and additional refs (e.g. FETCH_HEAD, - * MERGE_HEAD, ...) + * Returns a collection of all refs and additional refs. + * + * Additional refs which don't start with "refs/" are not returned because + * they should not save objects from being garbage collected. Examples for + * such references are ORIG_HEAD, MERGE_HEAD, FETCH_HEAD and + * CHERRY_PICK_HEAD. * * @return a collection of refs pointing to live objects. * @throws IOException @@ -668,7 +672,12 @@ public class GC { if (!addl.isEmpty()) { List<Ref> all = new ArrayList<>(refs.size() + addl.size()); all.addAll(refs); - all.addAll(addl); + // add additional refs which start with refs/ + for (Ref r : addl) { + if (r.getName().startsWith(Constants.R_REFS)) { + all.add(r); + } + } return all; } return refs; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectoryInserter.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectoryInserter.java index fb411722be..9820e0ea39 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectoryInserter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectoryInserter.java @@ -136,7 +136,7 @@ class ObjectDirectoryInserter extends ObjectInserter { @Override public ObjectReader newReader() { - return new WindowCursor(db); + return new WindowCursor(db, this); } @Override 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 4bb2982b48..e5ca736824 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 @@ -688,7 +688,7 @@ public class RefDirectory extends RefDatabase { newLoose = curLoose.remove(idx); } while (!looseRefs.compareAndSet(curLoose, newLoose)); int levels = levelsIn(refName) - 2; - delete(fileFor(refName), levels); + delete(refFile, levels, rLck); } } finally { rLck.unlock(); @@ -1062,13 +1062,24 @@ public class RefDirectory extends RefDatabase { } static void delete(final File file, final int depth) throws IOException { - if (!file.delete() && file.isFile()) - throw new IOException(MessageFormat.format(JGitText.get().fileCannotBeDeleted, file)); + delete(file, depth, null); + } + private static void delete(final File file, final int depth, LockFile rLck) + throws IOException { + if (!file.delete() && file.isFile()) { + throw new IOException(MessageFormat.format( + JGitText.get().fileCannotBeDeleted, file)); + } + + if (rLck != null) { + rLck.unlock(); // otherwise cannot delete dir below + } File dir = file.getParentFile(); for (int i = 0; i < depth; ++i) { - if (!dir.delete()) + if (!dir.delete()) { break; // ignore problem here + } dir = dir.getParentFile(); } } 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 a555e10d47..a2c0561ae1 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 @@ -53,6 +53,7 @@ import java.util.Set; import java.util.zip.DataFormatException; import java.util.zip.Inflater; +import org.eclipse.jgit.annotations.Nullable; import org.eclipse.jgit.errors.IncorrectObjectTypeException; import org.eclipse.jgit.errors.MissingObjectException; import org.eclipse.jgit.errors.StoredObjectRepresentationNotAvailableException; @@ -69,6 +70,7 @@ import org.eclipse.jgit.lib.BitmapIndex.BitmapBuilder; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.InflaterCache; import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.lib.ObjectInserter; import org.eclipse.jgit.lib.ObjectLoader; import org.eclipse.jgit.lib.ObjectReader; import org.eclipse.jgit.lib.ProgressMonitor; @@ -84,10 +86,20 @@ final class WindowCursor extends ObjectReader implements ObjectReuseAsIs { private DeltaBaseCache baseCache; + @Nullable + private final ObjectInserter createdFromInserter; + final FileObjectDatabase db; WindowCursor(FileObjectDatabase db) { this.db = db; + this.createdFromInserter = null; + } + + WindowCursor(FileObjectDatabase db, + @Nullable ObjectDirectoryInserter createdFromInserter) { + this.db = db; + this.createdFromInserter = createdFromInserter; } DeltaBaseCache getDeltaBaseCache() { @@ -329,6 +341,12 @@ final class WindowCursor extends ObjectReader implements ObjectReuseAsIs { return WindowCache.getStreamFileThreshold(); } + @Override + @Nullable + public ObjectInserter getCreatedFromInserter() { + return createdFromInserter; + } + /** Release the current window cursor. */ @Override public void close() { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftree/RefTreeBatch.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftree/RefTreeBatch.java index a55a9f51e7..1cccd79810 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftree/RefTreeBatch.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftree/RefTreeBatch.java @@ -98,8 +98,12 @@ class RefTreeBatch extends BatchRefUpdate { } if (c.getType() == UPDATE_NONFASTFORWARD) { c.setResult(REJECTED_NONFASTFORWARD); - ReceiveCommand.abort(getCommands()); - return; + if (isAtomic()) { + ReceiveCommand.abort(getCommands()); + return; + } else { + continue; + } } } todo.add(new Command(rw, c)); 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 d7e930831e..35cadd3c97 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchRefUpdate.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchRefUpdate.java @@ -89,6 +89,9 @@ public class BatchRefUpdate { /** Push certificate associated with this update. */ private PushCertificate pushCert; + /** Whether updates should be atomic. */ + private boolean atomic; + /** * Initialize a new batch update. * @@ -98,6 +101,7 @@ public class BatchRefUpdate { protected BatchRefUpdate(RefDatabase refdb) { this.refdb = refdb; this.commands = new ArrayList<ReceiveCommand>(); + this.atomic = refdb.performsAtomicTransactions(); } /** @@ -200,6 +204,36 @@ public class BatchRefUpdate { } /** + * Request that all updates in this batch be performed atomically. + * <p> + * When atomic updates are used, either all commands apply successfully, or + * none do. Commands that might have otherwise succeeded are rejected with + * {@code REJECTED_OTHER_REASON}. + * <p> + * This method only works if the underlying ref database supports atomic + * transactions, i.e. {@link RefDatabase#performsAtomicTransactions()} returns + * true. Calling this method with true if the underlying ref database does not + * support atomic transactions will cause all commands to fail with {@code + * REJECTED_OTHER_REASON}. + * + * @param atomic whether updates should be atomic. + * @return {@code this} + * @since 4.4 + */ + public BatchRefUpdate setAtomic(boolean atomic) { + this.atomic = atomic; + return this; + } + + /** + * @return atomic whether updates should be atomic. + * @since 4.4 + */ + public boolean isAtomic() { + return atomic; + } + + /** * Set a push certificate associated with this update. * <p> * This usually includes commands to update the refs in this batch, but is not @@ -271,6 +305,10 @@ public class BatchRefUpdate { * <p> * The default implementation of this method performs a sequential reference * update over each reference. + * <p> + * Implementations must respect the atomicity requirements of the underlying + * database as described in {@link #setAtomic(boolean)} and {@link + * RefDatabase#performsAtomicTransactions()}. * * @param walk * a RevWalk to parse tags in case the storage system wants to @@ -284,6 +322,17 @@ public class BatchRefUpdate { */ public void execute(RevWalk walk, ProgressMonitor monitor) throws IOException { + + if (atomic && !refdb.performsAtomicTransactions()) { + for (ReceiveCommand c : commands) { + if (c.getResult() == NOT_ATTEMPTED) { + c.setResult(REJECTED_OTHER_REASON, + JGitText.get().atomicRefUpdatesNotSupported); + } + } + return; + } + monitor.beginTask(JGitText.get().updatingReferences, commands.size()); List<ReceiveCommand> commands2 = new ArrayList<ReceiveCommand>( commands.size()); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchingProgressMonitor.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchingProgressMonitor.java index 39856c0c98..a3859abb23 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchingProgressMonitor.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BatchingProgressMonitor.java @@ -43,55 +43,11 @@ package org.eclipse.jgit.lib; -import java.util.concurrent.Executors; import java.util.concurrent.Future; -import java.util.concurrent.ScheduledThreadPoolExecutor; -import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; /** ProgressMonitor that batches update events. */ public abstract class BatchingProgressMonitor implements ProgressMonitor { - private static final ScheduledThreadPoolExecutor alarmQueue; - - static final Object alarmQueueKiller; - - static { - // To support garbage collection, start our thread but - // swap out the thread factory. When our class is GC'd - // the alarmQueueKiller will finalize and ask the executor - // to shutdown, ending the worker. - // - int threads = 1; - alarmQueue = new ScheduledThreadPoolExecutor(threads, - new ThreadFactory() { - private final ThreadFactory baseFactory = Executors - .defaultThreadFactory(); - - public Thread newThread(Runnable taskBody) { - Thread thr = baseFactory.newThread(taskBody); - thr.setName("JGit-AlarmQueue"); //$NON-NLS-1$ - thr.setDaemon(true); - return thr; - } - }); - alarmQueue.setContinueExistingPeriodicTasksAfterShutdownPolicy(false); - alarmQueue.setExecuteExistingDelayedTasksAfterShutdownPolicy(false); - alarmQueue.prestartAllCoreThreads(); - - // Now that the threads are running, its critical to swap out - // our own thread factory for one that isn't in the ClassLoader. - // This allows the class to GC. - // - alarmQueue.setThreadFactory(Executors.defaultThreadFactory()); - - alarmQueueKiller = new Object() { - @Override - protected void finalize() { - alarmQueue.shutdownNow(); - } - }; - } - private long delayStartTime; private TimeUnit delayStartUnit = TimeUnit.MILLISECONDS; @@ -219,7 +175,7 @@ public abstract class BatchingProgressMonitor implements ProgressMonitor { void delay(long time, TimeUnit unit) { display = false; - timerFuture = alarmQueue.schedule(this, time, unit); + timerFuture = WorkQueue.getExecutor().schedule(this, time, unit); } public void run() { @@ -254,7 +210,8 @@ public abstract class BatchingProgressMonitor implements ProgressMonitor { private void restartTimer() { display = false; - timerFuture = alarmQueue.schedule(this, 1, TimeUnit.SECONDS); + timerFuture = WorkQueue.getExecutor().schedule(this, 1, + TimeUnit.SECONDS); } void end(BatchingProgressMonitor pm) { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BlobBasedConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BlobBasedConfig.java index 7d52991df0..8958ce7e85 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BlobBasedConfig.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BlobBasedConfig.java @@ -80,8 +80,7 @@ public class BlobBasedConfig extends Config { throws ConfigInvalidException { super(base); final String decoded; - if (blob.length >= 3 && blob[0] == (byte) 0xEF - && blob[1] == (byte) 0xBB && blob[2] == (byte) 0xBF) { + if (isUtf8(blob)) { decoded = RawParseUtils.decode(RawParseUtils.UTF8_CHARSET, blob, 3, blob.length); } else { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BranchTrackingStatus.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BranchTrackingStatus.java index 1525e5b187..d4fccf9070 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/BranchTrackingStatus.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/BranchTrackingStatus.java @@ -79,11 +79,11 @@ public class BranchTrackingStatus { if (trackingBranch == null) return null; - Ref tracking = repository.getRef(trackingBranch); + Ref tracking = repository.exactRef(trackingBranch); if (tracking == null) return null; - Ref local = repository.getRef(fullBranchName); + Ref local = repository.exactRef(fullBranchName); if (local == null) return null; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Config.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Config.java index e48386d024..1e1d14737a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Config.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Config.java @@ -51,12 +51,18 @@ package org.eclipse.jgit.lib; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Set; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.eclipse.jgit.errors.ConfigInvalidException; import org.eclipse.jgit.events.ConfigChangedEvent; @@ -64,6 +70,8 @@ import org.eclipse.jgit.events.ConfigChangedListener; import org.eclipse.jgit.events.ListenerHandle; import org.eclipse.jgit.events.ListenerList; import org.eclipse.jgit.internal.JGitText; +import org.eclipse.jgit.util.IO; +import org.eclipse.jgit.util.RawParseUtils; import org.eclipse.jgit.util.StringUtils; @@ -75,6 +83,7 @@ public class Config { private static final long KiB = 1024; private static final long MiB = 1024 * KiB; private static final long GiB = 1024 * MiB; + private static final int MAX_DEPTH = 10; /** the change listeners */ private final ListenerList listeners = new ListenerList(); @@ -485,6 +494,123 @@ public class Config { } /** + * Parse a numerical time unit, such as "1 minute", from the configuration. + * + * @param section + * section the key is in. + * @param subsection + * subsection the key is in, or null if not in a subsection. + * @param name + * the key name. + * @param defaultValue + * default value to return if no value was present. + * @param wantUnit + * the units of {@code defaultValue} and the return value, as + * well as the units to assume if the value does not contain an + * indication of the units. + * @return the value, or {@code defaultValue} if not set, expressed in + * {@code units}. + * @since 4.4 + */ + public long getTimeUnit(String section, String subsection, String name, + long defaultValue, TimeUnit wantUnit) { + String valueString = getString(section, subsection, name); + + if (valueString == null) { + return defaultValue; + } + + String s = valueString.trim(); + if (s.length() == 0) { + return defaultValue; + } + + if (s.startsWith("-")/* negative */) { //$NON-NLS-1$ + throw notTimeUnit(section, subsection, name, valueString); + } + + Matcher m = Pattern.compile("^(0|[1-9][0-9]*)\\s*(.*)$") //$NON-NLS-1$ + .matcher(valueString); + if (!m.matches()) { + return defaultValue; + } + + String digits = m.group(1); + String unitName = m.group(2).trim(); + + TimeUnit inputUnit; + int inputMul; + + if (unitName.isEmpty()) { + inputUnit = wantUnit; + inputMul = 1; + + } else if (match(unitName, "ms", "milliseconds")) { //$NON-NLS-1$ //$NON-NLS-2$ + inputUnit = TimeUnit.MILLISECONDS; + inputMul = 1; + + } else if (match(unitName, "s", "sec", "second", "seconds")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + inputUnit = TimeUnit.SECONDS; + inputMul = 1; + + } else if (match(unitName, "m", "min", "minute", "minutes")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + inputUnit = TimeUnit.MINUTES; + inputMul = 1; + + } else if (match(unitName, "h", "hr", "hour", "hours")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ + inputUnit = TimeUnit.HOURS; + inputMul = 1; + + } else if (match(unitName, "d", "day", "days")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + inputUnit = TimeUnit.DAYS; + inputMul = 1; + + } else if (match(unitName, "w", "week", "weeks")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + inputUnit = TimeUnit.DAYS; + inputMul = 7; + + } else if (match(unitName, "mon", "month", "months")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + inputUnit = TimeUnit.DAYS; + inputMul = 30; + + } else if (match(unitName, "y", "year", "years")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + inputUnit = TimeUnit.DAYS; + inputMul = 365; + + } else { + throw notTimeUnit(section, subsection, name, valueString); + } + + try { + return wantUnit.convert(Long.parseLong(digits) * inputMul, + inputUnit); + } catch (NumberFormatException nfe) { + throw notTimeUnit(section, subsection, unitName, valueString); + } + } + + private static boolean match(final String a, final String... cases) { + for (final String b : cases) { + if (b != null && b.equalsIgnoreCase(a)) { + return true; + } + } + return false; + } + + private IllegalArgumentException notTimeUnit(String section, + String subsection, String name, String valueString) { + if (subsection != null) { + return new IllegalArgumentException( + MessageFormat.format(JGitText.get().invalidTimeUnitValue3, + section, subsection, name, valueString)); + } + return new IllegalArgumentException( + MessageFormat.format(JGitText.get().invalidTimeUnitValue2, + section, name, valueString)); + } + + /** * @param section * section to search for. * @return set of all subsections of specified section within this @@ -633,12 +759,13 @@ public class Config { private String getRawString(final String section, final String subsection, final String name) { String[] lst = getRawStringList(section, subsection, name); - if (lst != null) - return lst[0]; - else if (baseConfig != null) + if (lst != null) { + return lst[lst.length - 1]; + } else if (baseConfig != null) { return baseConfig.getRawString(section, subsection, name); - else + } else { return null; + } } private String[] getRawStringList(String section, String subsection, @@ -855,7 +982,8 @@ public class Config { * * <pre> * [section "subsection"] - * name = value + * name = value1 + * name = value2 * </pre> * * @param section @@ -1025,6 +1153,15 @@ public class Config { * made to {@code this}. */ public void fromText(final String text) throws ConfigInvalidException { + state.set(newState(fromTextRecurse(text, 1))); + } + + private List<ConfigLine> fromTextRecurse(final String text, int depth) + throws ConfigInvalidException { + if (depth > MAX_DEPTH) { + throw new ConfigInvalidException( + JGitText.get().tooManyIncludeRecursions); + } final List<ConfigLine> newEntries = new ArrayList<ConfigLine>(); final StringReader in = new StringReader(text); ConfigLine last = null; @@ -1083,11 +1220,44 @@ public class Config { } else e.value = readValue(in, false, -1); + if (e.section.equals("include")) { //$NON-NLS-1$ + addIncludedConfig(newEntries, e, depth); + } } else throw new ConfigInvalidException(JGitText.get().invalidLineInConfigFile); } - state.set(newState(newEntries)); + return newEntries; + } + + private void addIncludedConfig(final List<ConfigLine> newEntries, + ConfigLine line, int depth) throws ConfigInvalidException { + if (!line.name.equals("path") || //$NON-NLS-1$ + line.value == null || line.value.equals(MAGIC_EMPTY_VALUE)) { + throw new ConfigInvalidException( + JGitText.get().invalidLineInConfigFile); + } + File path = new File(line.value); + try { + byte[] bytes = IO.readFully(path); + String decoded; + if (isUtf8(bytes)) { + decoded = RawParseUtils.decode(RawParseUtils.UTF8_CHARSET, + bytes, 3, bytes.length); + } else { + decoded = RawParseUtils.decode(bytes); + } + newEntries.addAll(fromTextRecurse(decoded, depth + 1)); + } catch (FileNotFoundException fnfe) { + if (path.exists()) { + throw new ConfigInvalidException(MessageFormat + .format(JGitText.get().cannotReadFile, path), fnfe); + } + } catch (IOException ioe) { + throw new ConfigInvalidException( + MessageFormat.format(JGitText.get().cannotReadFile, path), + ioe); + } } private ConfigSnapshot newState() { @@ -1107,6 +1277,19 @@ public class Config { state.set(newState()); } + /** + * Check if bytes should be treated as UTF-8 or not. + * + * @param bytes + * the bytes to check encoding for. + * @return true if bytes should be treated as UTF-8, false otherwise. + * @since 4.4 + */ + protected boolean isUtf8(final byte[] bytes) { + return bytes.length >= 3 && bytes[0] == (byte) 0xEF + && bytes[1] == (byte) 0xBB && bytes[2] == (byte) 0xBF; + } + private static String readSectionName(final StringReader in) throws ConfigInvalidException { final StringBuilder name = new StringBuilder(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectInserter.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectInserter.java index d9da65f03f..4c51279d05 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectInserter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectInserter.java @@ -143,7 +143,18 @@ public abstract class ObjectInserter implements AutoCloseable { } public ObjectReader newReader() { - return delegate().newReader(); + final ObjectReader dr = delegate().newReader(); + return new ObjectReader.Filter() { + @Override + protected ObjectReader delegate() { + return dr; + } + + @Override + public ObjectInserter getCreatedFromInserter() { + return ObjectInserter.Filter.this; + } + }; } public void flush() throws IOException { @@ -398,6 +409,9 @@ public abstract class ObjectInserter implements AutoCloseable { * visible to the repository. The returned reader should only be used from * the same thread as the inserter. Objects written by this inserter may not * be visible to {@code this.newReader().newReader()}. + * <p> + * The returned reader should return this inserter instance from {@link + * ObjectReader#getCreatedFromInserter()}. * * @since 3.5 * @return reader for any object, including an object recently inserted by 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 77cfb038cc..b23145d798 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectReader.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectReader.java @@ -50,6 +50,7 @@ import java.util.Iterator; import java.util.List; import java.util.Set; +import org.eclipse.jgit.annotations.Nullable; import org.eclipse.jgit.errors.IncorrectObjectTypeException; import org.eclipse.jgit.errors.MissingObjectException; import org.eclipse.jgit.internal.storage.pack.ObjectReuseAsIs; @@ -422,6 +423,17 @@ public abstract class ObjectReader implements AutoCloseable { } /** + * @return the {@link ObjectInserter} from which this reader was created + * using {@code inserter.newReader()}, or null if this reader was not + * created from an inserter. + * @since 4.4 + */ + @Nullable + public ObjectInserter getCreatedFromInserter() { + return null; + } + + /** * Release any resources used by this reader. * <p> * A reader that has been released can be used again, but may need to be @@ -431,4 +443,108 @@ public abstract class ObjectReader implements AutoCloseable { */ @Override public abstract void close(); + + /** + * Wraps a delegate ObjectReader. + * + * @since 4.4 + */ + public static abstract class Filter extends ObjectReader { + /** + * @return delegate ObjectReader to handle all processing. + * @since 4.4 + */ + protected abstract ObjectReader delegate(); + + @Override + public ObjectReader newReader() { + return delegate().newReader(); + } + + @Override + public AbbreviatedObjectId abbreviate(AnyObjectId objectId) + throws IOException { + return delegate().abbreviate(objectId); + } + + @Override + public AbbreviatedObjectId abbreviate(AnyObjectId objectId, int len) + throws IOException { + return delegate().abbreviate(objectId, len); + } + + @Override + public Collection<ObjectId> resolve(AbbreviatedObjectId id) + throws IOException { + return delegate().resolve(id); + } + + @Override + public boolean has(AnyObjectId objectId) throws IOException { + return delegate().has(objectId); + } + + @Override + public boolean has(AnyObjectId objectId, int typeHint) throws IOException { + return delegate().has(objectId, typeHint); + } + + @Override + public ObjectLoader open(AnyObjectId objectId) + throws MissingObjectException, IOException { + return delegate().open(objectId); + } + + @Override + public ObjectLoader open(AnyObjectId objectId, int typeHint) + throws MissingObjectException, IncorrectObjectTypeException, + IOException { + return delegate().open(objectId, typeHint); + } + + @Override + public Set<ObjectId> getShallowCommits() throws IOException { + return delegate().getShallowCommits(); + } + + @Override + public <T extends ObjectId> AsyncObjectLoaderQueue<T> open( + Iterable<T> objectIds, boolean reportMissing) { + return delegate().open(objectIds, reportMissing); + } + + @Override + public long getObjectSize(AnyObjectId objectId, int typeHint) + throws MissingObjectException, IncorrectObjectTypeException, + IOException { + return delegate().getObjectSize(objectId, typeHint); + } + + @Override + public <T extends ObjectId> AsyncObjectSizeQueue<T> getObjectSize( + Iterable<T> objectIds, boolean reportMissing) { + return delegate().getObjectSize(objectIds, reportMissing); + } + + @Override + public void setAvoidUnreachableObjects(boolean avoid) { + delegate().setAvoidUnreachableObjects(avoid); + } + + @Override + public BitmapIndex getBitmapIndex() throws IOException { + return delegate().getBitmapIndex(); + } + + @Override + @Nullable + public ObjectInserter getCreatedFromInserter() { + return delegate().getCreatedFromInserter(); + } + + @Override + public void close() { + delegate().close(); + } + } } 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 2ecc60c3b6..e08a98529d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/PersonIdent.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/PersonIdent.java @@ -111,6 +111,44 @@ public class PersonIdent implements Serializable { r.append(offsetMins); } + /** + * Sanitize the given string for use in an identity and append to output. + * <p> + * Trims whitespace from both ends and special characters {@code \n < >} that + * interfere with parsing; appends all other characters to the output. + * Analogous to the C git function {@code strbuf_addstr_without_crud}. + * + * @param r + * string builder to append to. + * @param str + * input string. + * @since 4.4 + */ + public static void appendSanitized(StringBuilder r, String str) { + // Trim any whitespace less than \u0020 as in String#trim(). + int i = 0; + while (i < str.length() && str.charAt(i) <= ' ') { + i++; + } + int end = str.length(); + while (end > i && str.charAt(end - 1) <= ' ') { + end--; + } + + for (; i < end; i++) { + char c = str.charAt(i); + switch (c) { + case '\n': + case '<': + case '>': + continue; + default: + r.append(c); + break; + } + } + } + private final String name; private final String emailAddress; @@ -217,7 +255,12 @@ public class PersonIdent implements Serializable { } /** - * Construct a {@link PersonIdent} + * Construct a {@link PersonIdent}. + * <p> + * Whitespace in the name and email is preserved for the lifetime of this + * object, but are trimmed by {@link #toExternalString()}. This means that + * parsing the result of {@link #toExternalString()} may not return an + * equivalent instance. * * @param aName * @param aEmailAddress @@ -276,6 +319,9 @@ public class PersonIdent implements Serializable { return tzOffset; } + /** + * Hashcode is based only on the email address and timestamp. + */ public int hashCode() { int hc = getEmailAddress().hashCode(); hc *= 31; @@ -300,9 +346,9 @@ public class PersonIdent implements Serializable { */ public String toExternalString() { final StringBuilder r = new StringBuilder(); - r.append(getName().trim()); + appendSanitized(r, getName()); r.append(" <"); //$NON-NLS-1$ - r.append(getEmailAddress().trim()); + appendSanitized(r, getEmailAddress()); r.append("> "); //$NON-NLS-1$ r.append(when / 1000); r.append(' '); @@ -328,3 +374,4 @@ public class PersonIdent implements Serializable { return r.toString(); } } + diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDatabase.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDatabase.java index c0c3862c8b..517c8aa538 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDatabase.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RefDatabase.java @@ -207,8 +207,25 @@ public abstract class RefDatabase { } /** - * @return if the database performs {@code newBatchUpdate()} as an atomic - * transaction. + * Whether the database is capable of performing batch updates as atomic + * transactions. + * <p> + * If true, by default {@link BatchRefUpdate} instances will perform updates + * atomically, meaning either all updates will succeed, or all updates will + * fail. It is still possible to turn off this behavior on a per-batch basis + * by calling {@code update.setAtomic(false)}. + * <p> + * If false, {@link BatchRefUpdate} instances will never perform updates + * atomically, and calling {@code update.setAtomic(true)} will cause the + * entire batch to fail with {@code REJECTED_OTHER_REASON}. + * <p> + * This definition of atomicity is stronger than what is provided by + * {@link org.eclipse.jgit.transport.ReceivePack}. {@code ReceivePack} will + * attempt to reject all commands if it knows in advance some commands may + * fail, even if the storage layer does not support atomic transactions. Here, + * atomicity applies even in the case of unforeseeable errors. + * + * @return whether transactions are atomic by default. * @since 3.6 */ public boolean performsAtomicTransactions() { 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 ba0dea39f5..7ec24998b4 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java @@ -63,6 +63,7 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; import org.eclipse.jgit.annotations.NonNull; import org.eclipse.jgit.annotations.Nullable; @@ -93,6 +94,8 @@ 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; /** * Represents a Git repository. @@ -103,6 +106,8 @@ import org.eclipse.jgit.util.io.SafeBufferedOutputStream; * This class is thread-safe. */ public abstract class Repository implements AutoCloseable { + private static Logger LOG = LoggerFactory.getLogger(Repository.class); + private static final ListenerList globalListeners = new ListenerList(); /** @return the global listener list observing all events in this JVM. */ @@ -113,6 +118,8 @@ public abstract class Repository implements AutoCloseable { /** Use counter */ final AtomicInteger useCnt = new AtomicInteger(1); + final AtomicLong closedAt = new AtomicLong(); + /** Metadata directory holding the repository's critical files. */ private final File gitDir; @@ -863,9 +870,24 @@ public abstract class Repository implements AutoCloseable { /** Decrement the use count, and maybe close resources. */ public void close() { - if (useCnt.decrementAndGet() == 0) { - doClose(); - RepositoryCache.unregister(this); + int newCount = useCnt.decrementAndGet(); + if (newCount == 0) { + if (RepositoryCache.isCached(this)) { + closedAt.set(System.currentTimeMillis()); + } else { + doClose(); + } + } else if (newCount == -1) { + // should not happen, only log when useCnt became negative to + // minimize number of log entries + LOG.warn(JGitText.get().corruptUseCnt); + if (LOG.isDebugEnabled()) { + IllegalStateException e = new IllegalStateException(); + LOG.debug("", e); //$NON-NLS-1$ + } + if (RepositoryCache.isCached(this)) { + closedAt.set(System.currentTimeMillis()); + } } } @@ -898,7 +920,7 @@ public abstract class Repository implements AutoCloseable { * This is essentially the same as doing: * * <pre> - * return getRef(Constants.HEAD).getTarget().getName() + * return exactRef(Constants.HEAD).getTarget().getName() * </pre> * * Except when HEAD is detached, in which case this method returns the @@ -912,7 +934,7 @@ public abstract class Repository implements AutoCloseable { */ @Nullable public String getFullBranch() throws IOException { - Ref head = getRef(Constants.HEAD); + Ref head = exactRef(Constants.HEAD); if (head == null) { return null; } 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 22b5fcd112..29ef084830 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RepositoryCache.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RepositoryCache.java @@ -52,17 +52,26 @@ 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; +import java.util.concurrent.TimeUnit; +import org.eclipse.jgit.annotations.NonNull; import org.eclipse.jgit.errors.RepositoryNotFoundException; import org.eclipse.jgit.internal.storage.file.FileRepository; import org.eclipse.jgit.util.FS; import org.eclipse.jgit.util.IO; import org.eclipse.jgit.util.RawParseUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** Cache of active {@link Repository} instances. */ public class RepositoryCache { private static final RepositoryCache cache = new RepositoryCache(); + private final static Logger LOG = LoggerFactory + .getLogger(RepositoryCache.class); + /** * Open an existing repository, reusing a cached instance if possible. * <p> @@ -138,10 +147,10 @@ public class RepositoryCache { * @param db * repository to unregister. */ - public static void close(final Repository db) { + public static void close(@NonNull final Repository db) { if (db.getDirectory() != null) { FileKey key = FileKey.exact(db.getDirectory(), db.getFS()); - cache.unregisterAndCloseRepository(key); + cache.unregisterAndCloseRepository(key, db); } } @@ -187,20 +196,69 @@ public class RepositoryCache { return cache.getKeys(); } + static boolean isCached(@NonNull Repository repo) { + File gitDir = repo.getDirectory(); + if (gitDir == null) { + return false; + } + FileKey key = new FileKey(gitDir, repo.getFS()); + Reference<Repository> repoRef = cache.cacheMap.get(key); + return repoRef != null && repoRef.get() == repo; + } + /** Unregister all repositories from the cache. */ public static void clear() { cache.clearAll(); } + static void clearExpired() { + cache.clearAllExpired(); + } + + static void reconfigure(RepositoryCacheConfig repositoryCacheConfig) { + cache.configureEviction(repositoryCacheConfig); + } + private final ConcurrentHashMap<Key, Reference<Repository>> cacheMap; private final Lock[] openLocks; + private ScheduledFuture<?> cleanupTask; + + private volatile long expireAfter; + private RepositoryCache() { cacheMap = new ConcurrentHashMap<Key, Reference<Repository>>(); openLocks = new Lock[4]; - for (int i = 0; i < openLocks.length; i++) + for (int i = 0; i < openLocks.length; i++) { openLocks[i] = new Lock(); + } + configureEviction(new RepositoryCacheConfig()); + } + + private void configureEviction( + RepositoryCacheConfig repositoryCacheConfig) { + expireAfter = repositoryCacheConfig.getExpireAfter(); + ScheduledThreadPoolExecutor scheduler = WorkQueue.getExecutor(); + synchronized (scheduler) { + if (cleanupTask != null) { + cleanupTask.cancel(false); + } + long delay = repositoryCacheConfig.getCleanupDelay(); + if (delay == RepositoryCacheConfig.NO_CLEANUP) { + return; + } + cleanupTask = scheduler.scheduleWithFixedDelay(new Runnable() { + @Override + public void run() { + try { + cache.clearAllExpired(); + } catch (Throwable e) { + LOG.error(e.getMessage(), e); + } + } + }, delay, delay, TimeUnit.MILLISECONDS); + } } @SuppressWarnings("resource") @@ -239,10 +297,20 @@ public class RepositoryCache { return oldRef != null ? oldRef.get() : null; } - private void unregisterAndCloseRepository(final Key location) { - Repository oldDb = unregisterRepository(location); - if (oldDb != null) { - oldDb.close(); + private boolean isExpired(Repository db) { + return db != null && db.useCnt.get() == 0 + && (System.currentTimeMillis() - db.closedAt.get() > expireAfter); + } + + private void unregisterAndCloseRepository(final Key location, + Repository db) { + synchronized (lockFor(location)) { + if (isExpired(db)) { + Repository oldDb = unregisterRepository(location); + if (oldDb != null) { + oldDb.close(); + } + } } } @@ -250,6 +318,15 @@ public class RepositoryCache { return new ArrayList<Key>(cacheMap.keySet()); } + private void clearAllExpired() { + for (Reference<Repository> ref : cacheMap.values()) { + Repository db = ref.get(); + if (isExpired(db)) { + RepositoryCache.close(db); + } + } + } + private void clearAll() { for (int stage = 0; stage < 2; stage++) { for (Iterator<Map.Entry<Key, Reference<Repository>>> i = cacheMap diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/RepositoryCacheConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RepositoryCacheConfig.java new file mode 100644 index 0000000000..428dea3e67 --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/RepositoryCacheConfig.java @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2016 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.lib; + +import java.util.concurrent.TimeUnit; + +/** + * Configuration parameters for JVM-wide repository cache used by JGit. + * + * @since 4.4 + */ +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. + */ + public static final long NO_CLEANUP = 0; + + /** + * Set cleanupDelayMillis to this value in order to auto-set it to minimum + * of 1/10 of expireAfterMillis and 10 minutes + */ + public static final long AUTO_CLEANUP_DELAY = -1; + + private long expireAfterMillis; + + private long cleanupDelayMillis; + + /** Create a default configuration. */ + public RepositoryCacheConfig() { + expireAfterMillis = TimeUnit.HOURS.toMillis(1); + cleanupDelayMillis = AUTO_CLEANUP_DELAY; + } + + /** + * @return the time an unused repository should expired and be evicted from + * the RepositoryCache in milliseconds. <b>Default is 1 hour.</b> + */ + public long getExpireAfter() { + return expireAfterMillis; + } + + /** + * @param expireAfterMillis + * the time an unused repository should expired and be evicted + * from the RepositoryCache in milliseconds. + */ + public void setExpireAfter(long expireAfterMillis) { + this.expireAfterMillis = expireAfterMillis; + } + + /** + * @return the delay between the periodic cleanup of expired repository in + * milliseconds. <b>Default is minimum of 1/10 of expireAfterMillis + * and 10 minutes</b> + */ + public long getCleanupDelay() { + if (cleanupDelayMillis < 0) { + return Math.min(expireAfterMillis / 10, + TimeUnit.MINUTES.toMillis(10)); + } + return cleanupDelayMillis; + } + + /** + * @param cleanupDelayMillis + * the delay between the periodic cleanup of expired repository + * in milliseconds. Set it to {@link #AUTO_CLEANUP_DELAY} to + * automatically derive cleanup delay from expireAfterMillis. + * <p> + * Set it to {@link #NO_CLEANUP} in order to switch off cache + * expiration. + * <p> + * If cache expiration is switched off the JVM still can evict + * cache entries when the JVM is running low on available heap + * memory. + */ + public void setCleanupDelay(long cleanupDelayMillis) { + this.cleanupDelayMillis = cleanupDelayMillis; + } + + /** + * Update properties by setting fields from the configuration. + * <p> + * If a property is not defined in the configuration, then it is left + * unmodified. + * + * @param config + * configuration to read properties from. + * @return {@code this}. + */ + public RepositoryCacheConfig fromConfig(Config config) { + setExpireAfter( + config.getTimeUnit("core", null, "repositoryCacheExpireAfter", //$NON-NLS-1$//$NON-NLS-2$ + getExpireAfter(), TimeUnit.MILLISECONDS)); + setCleanupDelay( + config.getTimeUnit("core", null, "repositoryCacheCleanupDelay", //$NON-NLS-1$ //$NON-NLS-2$ + AUTO_CLEANUP_DELAY, TimeUnit.MILLISECONDS)); + return this; + } + + /** + * Install this configuration as the live settings. + * <p> + * The new configuration is applied immediately. + */ + public void install() { + RepositoryCache.reconfigure(this); + } +} diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/WorkQueue.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/WorkQueue.java new file mode 100644 index 0000000000..9735d19e5e --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/WorkQueue.java @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2008-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.lib; + +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.ThreadFactory; + +/** + * Simple work queue to run tasks in the background + */ +class WorkQueue { + private static final ScheduledThreadPoolExecutor executor; + + static final Object executorKiller; + + static { + // To support garbage collection, start our thread but + // swap out the thread factory. When our class is GC'd + // the executorKiller will finalize and ask the executor + // to shutdown, ending the worker. + // + int threads = 1; + executor = new ScheduledThreadPoolExecutor(threads, + new ThreadFactory() { + private final ThreadFactory baseFactory = Executors + .defaultThreadFactory(); + + public Thread newThread(Runnable taskBody) { + Thread thr = baseFactory.newThread(taskBody); + thr.setName("JGit-WorkQueue"); //$NON-NLS-1$ + thr.setDaemon(true); + return thr; + } + }); + executor.setRemoveOnCancelPolicy(true); + executor.setContinueExistingPeriodicTasksAfterShutdownPolicy(false); + executor.setExecuteExistingDelayedTasksAfterShutdownPolicy(false); + executor.prestartAllCoreThreads(); + + // Now that the threads are running, its critical to swap out + // our own thread factory for one that isn't in the ClassLoader. + // This allows the class to GC. + // + executor.setThreadFactory(Executors.defaultThreadFactory()); + + executorKiller = new Object() { + @Override + protected void finalize() { + executor.shutdownNow(); + } + }; + } + + static ScheduledThreadPoolExecutor getExecutor() { + return executor; + } +} diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/RevFilter.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/RevFilter.java index 2a5cb2b2ac..14a98a10bf 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/RevFilter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/filter/RevFilter.java @@ -82,6 +82,7 @@ import org.eclipse.jgit.revwalk.RevWalk; * <b>Merge filters:</b> * <ul> * <li>Skip all merges: {@link #NO_MERGES}.</li> + * <li>Skip all non-merges: {@link #ONLY_MERGES}</li> * </ul> * * <p> @@ -143,6 +144,37 @@ public abstract class RevFilter { } } + /** + * Filter including only merge commits, excluding all commits with less than + * two parents (thread safe). + * + * @since 4.4 + */ + public static final RevFilter ONLY_MERGES = new OnlyMergesFilter(); + + private static final class OnlyMergesFilter extends RevFilter { + + @Override + public boolean include(RevWalk walker, RevCommit c) { + return c.getParentCount() >= 2; + } + + @Override + public RevFilter clone() { + return this; + } + + @Override + public boolean requiresCommitBody() { + return false; + } + + @Override + public String toString() { + return "ONLY_MERGES"; //$NON-NLS-1$ + } + } + /** Excludes commits with more than one parent (thread safe). */ public static final RevFilter NO_MERGES = new NoMergesFilter(); 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 702fd70765..4b4822c763 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 @@ -147,8 +147,7 @@ public class FileBasedConfig extends StoredConfig { snapshot = newSnapshot; } else { final String decoded; - if (in.length >= 3 && in[0] == (byte) 0xEF - && in[1] == (byte) 0xBB && in[2] == (byte) 0xBF) { + if (isUtf8(in)) { decoded = RawParseUtils.decode(RawParseUtils.UTF8_CHARSET, in, 3, in.length); utf8Bom = true; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/submodule/SubmoduleWalk.java b/org.eclipse.jgit/src/org/eclipse/jgit/submodule/SubmoduleWalk.java index 6263d4b74d..5b9e8d9029 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/submodule/SubmoduleWalk.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/submodule/SubmoduleWalk.java @@ -264,7 +264,7 @@ public class SubmoduleWalk implements AutoCloseable { String remoteName = null; // Look up remote URL associated wit HEAD ref - Ref ref = parent.getRef(Constants.HEAD); + Ref ref = parent.exactRef(Constants.HEAD); if (ref != null) { if (ref.isSymbolic()) ref = ref.getLeaf(); @@ -704,7 +704,7 @@ public class SubmoduleWalk implements AutoCloseable { if (subRepo == null) return null; try { - Ref head = subRepo.getRef(Constants.HEAD); + Ref head = subRepo.exactRef(Constants.HEAD); return head != null ? head.getLeaf().getName() : null; } finally { subRepo.close(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackPushConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackPushConnection.java index 963de35d41..9b8ba8098f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackPushConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackPushConnection.java @@ -57,6 +57,7 @@ import java.util.Set; import org.eclipse.jgit.errors.NoRemoteRepositoryException; import org.eclipse.jgit.errors.NotSupportedException; import org.eclipse.jgit.errors.PackProtocolException; +import org.eclipse.jgit.errors.TooLargeObjectInPackException; import org.eclipse.jgit.errors.TooLargePackException; import org.eclipse.jgit.errors.TransportException; import org.eclipse.jgit.internal.JGitText; @@ -328,12 +329,16 @@ public abstract class BasePackPushConnection extends BasePackConnection implemen if (!unpackLine.startsWith("unpack ")) //$NON-NLS-1$ throw new PackProtocolException(uri, MessageFormat.format(JGitText.get().unexpectedReportLine, unpackLine)); final String unpackStatus = unpackLine.substring("unpack ".length()); //$NON-NLS-1$ - if (unpackStatus.startsWith("error Pack exceeds the limit of")) //$NON-NLS-1$ + if (unpackStatus.startsWith("error Pack exceeds the limit of")) {//$NON-NLS-1$ throw new TooLargePackException(uri, unpackStatus.substring("error ".length())); //$NON-NLS-1$ - if (!unpackStatus.equals("ok")) //$NON-NLS-1$ + } else if (unpackStatus.startsWith("error Object too large")) {//$NON-NLS-1$ + throw new TooLargeObjectInPackException(uri, + unpackStatus.substring("error ".length())); //$NON-NLS-1$ + } else if (!unpackStatus.equals("ok")) { //$NON-NLS-1$ throw new TransportException(uri, MessageFormat.format( JGitText.get().errorOccurredDuringUnpackingOnTheRemoteEnd, unpackStatus)); + } String refLine; while ((refLine = pckIn.readString()) != PacketLineIn.END) { 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 a20e652553..b5f9e2f020 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseReceivePack.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseReceivePack.java @@ -176,6 +176,12 @@ public abstract class BaseReceivePack { /** Should an incoming transfer permit non-fast-forward requests? */ private boolean allowNonFastForwards; + /** + * Should the requested ref updates be performed as a single atomic + * transaction? + */ + private boolean atomic; + private boolean allowOfsDelta; private boolean allowQuiet = true; @@ -607,6 +613,25 @@ public abstract class BaseReceivePack { allowNonFastForwards = canRewind; } + /** + * @return true if the client's commands should be performed as a single + * atomic transaction. + * @since 4.4 + */ + public boolean isAtomic() { + return atomic; + } + + /** + * @param atomic + * true to perform the client's commands as a single atomic + * transaction. + * @since 4.4 + */ + public void setAtomic(boolean atomic) { + this.atomic = atomic; + } + /** @return identity of the user making the changes in the reflog. */ public PersonIdent getRefLogIdent() { return refLogIdent; @@ -1483,6 +1508,7 @@ public abstract class BaseReceivePack { BatchRefUpdate batch = db.getRefDatabase().newBatchUpdate(); batch.setAllowNonFastForwards(isAllowNonFastForwards()); + batch.setAtomic(isAtomic()); batch.setRefLogIdent(getRefLogIdent()); batch.setRefLogMessage("push", true); //$NON-NLS-1$ batch.addCommand(toApply); 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 6ed9bc8f17..f61e93fff2 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java @@ -201,6 +201,8 @@ public class ReceivePack extends BaseReceivePack { if (unpackError == null) { boolean atomic = isCapabilityEnabled(CAPABILITY_ATOMIC); + setAtomic(atomic); + validateCommands(); if (atomic && anyRejects()) failPendingCommands(); 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 9e6d1f68f5..862b3bdeb0 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/Transport.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/Transport.java @@ -629,7 +629,7 @@ public abstract class Transport implements AutoCloseable { for (final RefSpec spec : procRefs) { String srcSpec = spec.getSource(); - final Ref srcRef = db.getRef(srcSpec); + final Ref srcRef = db.findRef(srcSpec); if (srcRef != null) srcSpec = srcRef.getName(); 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 8b642bb980..e49ee87b73 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java @@ -82,6 +82,7 @@ import org.eclipse.jgit.lib.NullProgressMonitor; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ProgressMonitor; import org.eclipse.jgit.lib.Ref; +import org.eclipse.jgit.lib.RefDatabase; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.revwalk.AsyncRevObjectQueue; import org.eclipse.jgit.revwalk.DepthWalk; @@ -704,22 +705,22 @@ public class UploadPack { return statistics; } - private Map<String, Ref> getAdvertisedOrDefaultRefs() { + private Map<String, Ref> getAdvertisedOrDefaultRefs() throws IOException { if (refs == null) - setAdvertisedRefs(null); + setAdvertisedRefs(db.getRefDatabase().getRefs(RefDatabase.ALL)); return refs; } private void service() throws IOException { - if (biDirectionalPipe) - sendAdvertisedRefs(new PacketLineOutRefAdvertiser(pckOut)); - else if (requestValidator instanceof AnyRequestValidator) - advertised = Collections.emptySet(); - else - advertised = refIdSet(getAdvertisedOrDefaultRefs().values()); - boolean sendPack; try { + if (biDirectionalPipe) + sendAdvertisedRefs(new PacketLineOutRefAdvertiser(pckOut)); + else if (requestValidator instanceof AnyRequestValidator) + advertised = Collections.emptySet(); + else + advertised = refIdSet(getAdvertisedOrDefaultRefs().values()); + recvWants(); if (wantIds.isEmpty()) { preUploadHook.onBeginNegotiateRound(this, wantIds, 0); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java index 779b10e1bb..b4f12f4120 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS_POSIX.java @@ -122,7 +122,7 @@ public class FS_POSIX extends FS { .defaultCharset().name()))) { if (p.waitFor() == 0) { String s = lineRead.readLine(); - if (s.matches("0?\\d{3}")) { //$NON-NLS-1$ + if (s != null && s.matches("0?\\d{3}")) { //$NON-NLS-1$ return Integer.parseInt(s, 8); } } @@ -51,7 +51,7 @@ <groupId>org.eclipse.jgit</groupId> <artifactId>org.eclipse.jgit-parent</artifactId> <packaging>pom</packaging> - <version>4.3.2-SNAPSHOT</version> + <version>4.4.2-SNAPSHOT</version> <name>JGit - Parent</name> <url>${jgit-url}</url> @@ -188,14 +188,15 @@ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> - <maven.build.timestamp.format>yyyyMMddHHmm</maven.build.timestamp.format> <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> - <junit-version>4.11</junit-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> @@ -206,8 +207,8 @@ <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.1</maven-javadoc-plugin-version> - <tycho-extras-version>0.23.0</tycho-extras-version> + <maven-javadoc-plugin-version>2.10.3</maven-javadoc-plugin-version> + <tycho-extras-version>0.25.0</tycho-extras-version> <gson-version>2.2.4</gson-version> <!-- Properties to enable jacoco code coverage analysis --> @@ -259,23 +260,26 @@ <plugin> <artifactId>maven-compiler-plugin</artifactId> - <version>3.2</version> + <version>3.5.1</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> </configuration> </plugin> <plugin> <artifactId>maven-clean-plugin</artifactId> - <version>2.6.1</version> + <version>3.0.0</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> - <version>2.3</version> + <version>2.4.3</version> </plugin> <plugin> @@ -293,7 +297,7 @@ <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-source-plugin</artifactId> - <version>2.4</version> + <version>3.0.0</version> </plugin> <plugin> @@ -305,7 +309,7 @@ <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> - <version>2.18.1</version> + <version>2.19.1</version> <configuration> <forkCount>${test-fork-count}</forkCount> <reuseForks>true</reuseForks> @@ -315,13 +319,13 @@ <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>build-helper-maven-plugin</artifactId> - <version>1.9</version> + <version>1.10</version> </plugin> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>findbugs-maven-plugin</artifactId> - <version>3.0.0</version> + <version>3.0.3</version> <configuration> <findbugsXmlOutput>true</findbugsXmlOutput> <failOnError>false</failOnError> @@ -338,7 +342,7 @@ <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-pmd-plugin</artifactId> - <version>3.4</version> + <version>3.6</version> <configuration> <sourceEncoding>utf-8</sourceEncoding> <minimumTokens>100</minimumTokens> @@ -358,7 +362,7 @@ <plugin> <groupId>org.eclipse.cbi.maven.plugins</groupId> <artifactId>eclipse-jarsigner-plugin</artifactId> - <version>1.1.2</version> + <version>1.1.3</version> </plugin> <plugin> <groupId>org.eclipse.tycho.extras</groupId> @@ -373,24 +377,24 @@ <plugin> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven-plugin</artifactId> - <version>0.7.1.201405082137</version> + <version>0.7.6.201602180812</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-site-plugin</artifactId> - <version>3.4</version> + <version>3.5.1</version> <dependencies> <dependency><!-- add support for ssh/scp --> <groupId>org.apache.maven.wagon</groupId> <artifactId>wagon-ssh</artifactId> - <version>2.7</version> + <version>2.10</version> </dependency> </dependencies> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-report-plugin</artifactId> - <version>2.18.1</version> + <version>2.19.1</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> @@ -400,7 +404,7 @@ <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-project-info-reports-plugin</artifactId> - <version>2.8</version> + <version>2.9</version> </plugin> </plugins> </pluginManagement> @@ -453,6 +457,7 @@ <configuration> <encoding>${project.build.sourceEncoding}</encoding> <quiet>true</quiet> + <excludePackageNames>org.eclipse.jgit.http.test</excludePackageNames> <links> <link>http://docs.oracle.com/javase/7/docs/api</link> </links> @@ -525,12 +530,12 @@ <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>findbugs-maven-plugin</artifactId> - <version>3.0.0</version> + <version>3.0.3</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-report-plugin</artifactId> - <version>2.18.1</version> + <version>2.19.1</version> <configuration> <aggregate>true</aggregate> <alwaysGenerateSurefireReport>false</alwaysGenerateSurefireReport> diff --git a/tools/release.sh b/tools/release.sh index 7adb3758c0..d180bdf59e 100755 --- a/tools/release.sh +++ b/tools/release.sh @@ -47,6 +47,5 @@ git commit -a -s -m "$MSG" git tag -sf -m "$MSG" $1 # run the build -mvn clean install +mvn clean install -T 1C mvn clean install -f org.eclipse.jgit.packaging/pom.xml - |