Merge branch 'master' into stable-4.0

* master:
  Fix warnings in ObjectFilter
  Fix typo in reflog message written by RebaseCommand.tryFastForward()
  Correct @since tags for ObjectFilter
  Fix typo in ObjectWalk#getObjectFilter javadoc
  Allow ObjectWalk to be filtered by an arbitrary predicate
  Remove SoftReference from dfs.DeltaBaseCache
  Fix memory leak in dfs.DeltaBaseCase
  Update to Jetty 9.2.10
  Update javax.servlet to 3.1
  Use ANY_DIFF filter in ResolveMerger only for bare repositories
  FS_POSIX: Rework umask detection to make it settable
  Expose disposeBody() on RevCommit and RevTag
  ObjectReader: remove the walkAdvice API
  RevWalk: Discard uninteresting commits unless RevSort.BOUNDARY
  ObjectWalk: make setRetainBody(false) the default
  Do not concatenate strings as arguments to StringBuilder.append()
  IndexDiffFilter: Simplify a boolean expression
  GroupHead: Remove a redundant call to String.format()
  FS_Win32: Avoid an IOException on Windows if bash is not in PATH
  Skip logging stack trace on corrupt objects
  Add repository name to failures in HTTP server log
  Fix possible AIOOB in DirCacheTree.contains()
  Delete deprecated PackWriter.preparePack() methods
  Delete deprecated class IgnoreRule
  Delete deprecated checkoutEntry() methods in DirCacheCheckout
  Fix IllegalArgumentException in AmazonS3

Change-Id: Ica3d4f0675c81684fbe48fcf0053f2a949bc5c9b
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
This commit is contained in:
Matthias Sohn 2015-05-19 16:07:17 +02:00
commit fd04e0548f
64 changed files with 852 additions and 1571 deletions

View File

@ -15,9 +15,10 @@ Export-Package: org.eclipse.jgit.http.server;version="4.0.0",
javax.servlet.http"
Bundle-ActivationPolicy: lazy
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Import-Package: javax.servlet;version="[2.5.0,3.0.0)",
javax.servlet.http;version="[2.5.0,3.0.0)",
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.0.0,4.1.0)",
org.eclipse.jgit.internal.storage.dfs;version="[4.0.0,4.1.0)",
org.eclipse.jgit.internal.storage.file;version="[4.0.0,4.1.0)",
org.eclipse.jgit.lib;version="[4.0.0,4.1.0)",
org.eclipse.jgit.nls;version="[4.0.0,4.1.0)",

View File

@ -11,8 +11,8 @@ encodingNotSupportedByThisLibrary={0} "{1}": not supported by this library.
expectedRepositoryAttribute=Expected Repository attribute
filterMustNotBeNull=filter must not be null
internalServerError=Internal server error
internalErrorDuringReceivePack=Internal error during receive-pack
internalErrorDuringUploadPack=Internal error during upload-pack
internalErrorDuringReceivePack=Internal error during receive-pack to {0}
internalErrorDuringUploadPack=Internal error during upload-pack from {0}
internalServerErrorRequestAttributeWasAlreadySet=Internal server error, request attribute {0} was already set when {1} was invoked.
invalidBoolean=Invalid boolean {0} = {1}
invalidIndex=Invalid index: {0}
@ -21,6 +21,7 @@ noResolverAvailable=No resolver available
parameterNotSet=Parameter {0} not set
pathForParamNotFound={0} (for {1}) not found
pathNotSupported={0} not supported
receivedCorruptObject=Cannot receive {0} into {1}
repositoryAccessForbidden=Git access forbidden
repositoryNotFound=Git repository not found
servletAlreadyInitialized=Servlet already initialized

View File

@ -76,6 +76,7 @@ public static HttpServerText get() {
/***/ public String parameterNotSet;
/***/ public String pathForParamNotFound;
/***/ public String pathNotSupported;
/***/ public String receivedCorruptObject;
/***/ public String repositoryAccessForbidden;
/***/ public String repositoryNotFound;
/***/ public String servletAlreadyInitialized;

View File

@ -62,6 +62,7 @@
import static org.eclipse.jgit.util.HttpSupport.HDR_USER_AGENT;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.List;
import javax.servlet.Filter;
@ -74,6 +75,7 @@
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jgit.errors.CorruptObjectException;
import org.eclipse.jgit.errors.UnpackException;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.transport.InternalHttpServerGlue;
@ -190,16 +192,23 @@ public void flush() throws IOException {
rp.receive(getInputStream(req), out, null);
out.close();
} catch (CorruptObjectException e ) {
// This should be already reported to the client.
getServletContext().log(MessageFormat.format(
HttpServerText.get().receivedCorruptObject,
e.getMessage(),
ServletUtils.identify(rp.getRepository())));
consumeRequestBody(req);
out.close();
} catch (UnpackException e) {
// This should be already reported to the client.
getServletContext().log(
HttpServerText.get().internalErrorDuringReceivePack,
e.getCause());
log(rp.getRepository(), e.getCause());
consumeRequestBody(req);
out.close();
} catch (Throwable e) {
getServletContext().log(HttpServerText.get().internalErrorDuringReceivePack, e);
log(rp.getRepository(), e);
if (!rsp.isCommitted()) {
rsp.reset();
sendError(req, rsp, SC_INTERNAL_SERVER_ERROR);
@ -207,4 +216,10 @@ public void flush() throws IOException {
return;
}
}
private void log(Repository git, Throwable e) {
getServletContext().log(MessageFormat.format(
HttpServerText.get().internalErrorDuringReceivePack,
ServletUtils.identify(git)), e);
}
}

View File

@ -62,6 +62,7 @@
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jgit.internal.storage.dfs.DfsRepository;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
@ -273,6 +274,15 @@ private static String etag(final byte[] content) {
return ObjectId.fromRaw(md.digest()).getName();
}
static String identify(Repository git) {
if (git instanceof DfsRepository) {
return ((DfsRepository) git).getDescription().getRepositoryName();
} else if (git.getDirectory() != null) {
return git.getDirectory().getPath();
}
return "unknown";
}
private ServletUtils() {
// static utility class only
}

View File

@ -61,6 +61,7 @@
import static org.eclipse.jgit.util.HttpSupport.HDR_USER_AGENT;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.List;
import javax.servlet.Filter;
@ -76,9 +77,9 @@
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.transport.InternalHttpServerGlue;
import org.eclipse.jgit.transport.RefAdvertiser.PacketLineOutRefAdvertiser;
import org.eclipse.jgit.transport.ServiceMayNotContinueException;
import org.eclipse.jgit.transport.UploadPack;
import org.eclipse.jgit.transport.UploadPackInternalServerErrorException;
import org.eclipse.jgit.transport.ServiceMayNotContinueException;
import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException;
import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;
import org.eclipse.jgit.transport.resolver.UploadPackFactory;
@ -203,14 +204,12 @@ public void flush() throws IOException {
} catch (UploadPackInternalServerErrorException e) {
// Special case exception, error message was sent to client.
getServletContext().log(
HttpServerText.get().internalErrorDuringUploadPack,
e.getCause());
log(up.getRepository(), e.getCause());
consumeRequestBody(req);
out.close();
} catch (Throwable e) {
getServletContext().log(HttpServerText.get().internalErrorDuringUploadPack, e);
log(up.getRepository(), e);
if (!rsp.isCommitted()) {
rsp.reset();
sendError(req, rsp, SC_INTERNAL_SERVER_ERROR);
@ -218,4 +217,10 @@ public void flush() throws IOException {
return;
}
}
private void log(Repository git, Throwable e) {
getServletContext().log(MessageFormat.format(
HttpServerText.get().internalErrorDuringUploadPack,
ServletUtils.identify(git)), e);
}
}

View File

@ -6,22 +6,22 @@ Bundle-Version: 4.0.0.qualifier
Bundle-Vendor: %provider_name
Bundle-Localization: plugin
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Import-Package: javax.servlet;version="[2.5.0,3.0.0)",
javax.servlet.http;version="[2.5.0,3.0.0)",
org.eclipse.jetty.continuation;version="[7.6.0,8.0.0)",
org.eclipse.jetty.http;version="[7.6.0,8.0.0)",
org.eclipse.jetty.io;version="[7.6.0,8.0.0)",
org.eclipse.jetty.security;version="[7.6.0,8.0.0)",
org.eclipse.jetty.security.authentication;version="[7.6.0,8.0.0)",
org.eclipse.jetty.server;version="[7.6.0,8.0.0)",
org.eclipse.jetty.server.handler;version="[7.6.0,8.0.0)",
org.eclipse.jetty.server.nio;version="[7.6.0,8.0.0)",
org.eclipse.jetty.servlet;version="[7.6.0,8.0.0)",
org.eclipse.jetty.util;version="[7.6.0,8.0.0)",
org.eclipse.jetty.util.component;version="[7.6.0,8.0.0)",
org.eclipse.jetty.util.log;version="[7.6.0,8.0.0)",
org.eclipse.jetty.util.security;version="[7.6.0,8.0.0)",
org.eclipse.jetty.util.thread;version="[7.6.0,8.0.0)",
Import-Package: javax.servlet;version="[2.5.0,3.2.0)",
javax.servlet.http;version="[2.5.0,3.2.0)",
org.eclipse.jetty.continuation;version="[9.0.0,10.0.0)",
org.eclipse.jetty.http;version="[9.0.0,10.0.0)",
org.eclipse.jetty.io;version="[9.0.0,10.0.0)",
org.eclipse.jetty.security;version="[9.0.0,10.0.0)",
org.eclipse.jetty.security.authentication;version="[9.0.0,10.0.0)",
org.eclipse.jetty.server;version="[9.0.0,10.0.0)",
org.eclipse.jetty.server.handler;version="[9.0.0,10.0.0)",
org.eclipse.jetty.server.nio;version="[9.0.0,10.0.0)",
org.eclipse.jetty.servlet;version="[9.0.0,10.0.0)",
org.eclipse.jetty.util;version="[9.0.0,10.0.0)",
org.eclipse.jetty.util.component;version="[9.0.0,10.0.0)",
org.eclipse.jetty.util.log;version="[9.0.0,10.0.0)",
org.eclipse.jetty.util.security;version="[9.0.0,10.0.0)",
org.eclipse.jetty.util.thread;version="[9.0.0,10.0.0)",
org.eclipse.jgit.errors;version="[4.0.0,4.1.0)",
org.eclipse.jgit.http.server;version="[4.0.0,4.1.0)",
org.eclipse.jgit.http.server.glue;version="[4.0.0,4.1.0)",

View File

@ -133,7 +133,7 @@ private static final class R extends HttpServletRequestWrapper {
private final String host;
R(final String user, final String host) {
super(new Request() /* can't pass null, sigh */);
super(new Request(null, null) /* can't pass null, sigh */);
this.user = user;
this.host = host;
}

View File

@ -204,7 +204,7 @@ private static final class R extends HttpServletRequestWrapper {
private final String host;
R(final String user, final String host) {
super(new Request() /* can't pass null, sigh */);
super(new Request(null, null) /* can't pass null, sigh */);
this.user = user;
this.host = host;
}

View File

@ -160,7 +160,7 @@ private static final class R extends HttpServletRequestWrapper {
private final String host;
R(final String user, final String host) {
super(new Request() /* can't pass null, sigh */);
super(new Request(null, null) /* can't pass null, sigh */);
this.user = user;
this.host = host;
}

View File

@ -199,7 +199,8 @@ public void testListRemote() throws IOException {
.startsWith("JGit/"));
assertEquals("*/*", info.getRequestHeader(HDR_ACCEPT));
assertEquals(200, info.getStatus());
assertEquals("text/plain;charset=UTF-8", info
assertEquals("text/plain; charset=UTF-8",
info
.getResponseHeader(HDR_CONTENT_TYPE));
AccessEvent head = requests.get(1);
@ -268,7 +269,8 @@ public void testInitialClone_Packed() throws Exception {
assertEquals("GET", req.get(0).getMethod());
assertEquals(0, req.get(0).getParameters().size());
assertEquals(200, req.get(0).getStatus());
assertEquals("text/plain;charset=UTF-8", req.get(0).getResponseHeader(
assertEquals("text/plain; charset=UTF-8",
req.get(0).getResponseHeader(
HDR_CONTENT_TYPE));
}

View File

@ -59,9 +59,11 @@
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
@ -72,7 +74,6 @@
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.servlet.FilterMapping;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jgit.errors.RemoteRepositoryException;
@ -185,7 +186,8 @@ public void init(FilterConfig filterConfig) throws ServletException {
public void destroy() {
//
}
}), "/" + srcName + "/git-upload-pack", FilterMapping.DEFAULT);
}), "/" + srcName + "/git-upload-pack",
EnumSet.of(DispatcherType.REQUEST));
broken.addServlet(new ServletHolder(gs), "/*");
server.setUp();
@ -480,7 +482,7 @@ public void testInitialClone_BrokenServer() throws Exception {
} catch (TransportException err) {
String exp = brokenURI + ": expected"
+ " Content-Type application/x-git-upload-pack-result;"
+ " received Content-Type text/plain;charset=UTF-8";
+ " received Content-Type text/plain; charset=UTF-8";
assertEquals(exp, err.getMessage());
}
} finally {
@ -504,8 +506,8 @@ public void testInitialClone_BrokenServer() throws Exception {
assertEquals(join(brokenURI, "git-upload-pack"), service.getPath());
assertEquals(0, service.getParameters().size());
assertEquals(200, service.getStatus());
assertEquals("text/plain;charset=UTF-8", service
.getResponseHeader(HDR_CONTENT_TYPE));
assertEquals("text/plain; charset=UTF-8",
service.getResponseHeader(HDR_CONTENT_TYPE));
}
@Test

View File

@ -7,19 +7,19 @@ Bundle-Localization: plugin
Bundle-Vendor: %provider_name
Bundle-ActivationPolicy: lazy
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Import-Package: javax.servlet;version="[2.5.0,3.0.0)",
javax.servlet.http;version="[2.5.0,3.0.0)",
Import-Package: javax.servlet;version="[2.5.0,3.2.0)",
javax.servlet.http;version="[2.5.0,3.2.0)",
org.apache.commons.logging;version="[1.1.1,2.0.0)",
org.eclipse.jetty.http;version="[7.6.0,8.0.0)",
org.eclipse.jetty.security;version="[7.6.0,8.0.0)",
org.eclipse.jetty.security.authentication;version="[7.6.0,8.0.0)",
org.eclipse.jetty.server;version="[7.6.0,8.0.0)",
org.eclipse.jetty.server.handler;version="[7.6.0,8.0.0)",
org.eclipse.jetty.server.nio;version="[7.6.0,8.0.0)",
org.eclipse.jetty.servlet;version="[7.6.0,8.0.0)",
org.eclipse.jetty.util.component;version="[7.6.0,8.0.0)",
org.eclipse.jetty.util.log;version="[7.6.0,8.0.0)",
org.eclipse.jetty.util.security;version="[7.6.0,8.0.0)",
org.eclipse.jetty.http;version="[9.0.0,10.0.0)",
org.eclipse.jetty.security;version="[9.0.0,10.0.0)",
org.eclipse.jetty.security.authentication;version="[9.0.0,10.0.0)",
org.eclipse.jetty.server;version="[9.0.0,10.0.0)",
org.eclipse.jetty.server.handler;version="[9.0.0,10.0.0)",
org.eclipse.jetty.server.nio;version="[9.0.0,10.0.0)",
org.eclipse.jetty.servlet;version="[9.0.0,10.0.0)",
org.eclipse.jetty.util.component;version="[9.0.0,10.0.0)",
org.eclipse.jetty.util.log;version="[9.0.0,10.0.0)",
org.eclipse.jetty.util.security;version="[9.0.0,10.0.0)",
org.eclipse.jgit.errors;version="[4.0.0,4.1.0)",
org.eclipse.jgit.http.server;version="[4.0.0,4.1.0)",
org.eclipse.jgit.internal.storage.file;version="[4.0.0,4.1.0)",

View File

@ -60,10 +60,12 @@
import org.eclipse.jetty.security.MappedLoginService;
import org.eclipse.jetty.security.authentication.BasicAuthenticator;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.UserIdentity;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.eclipse.jetty.server.nio.SelectChannelConnector;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.util.security.Constraint;
import org.eclipse.jetty.util.security.Password;
@ -95,14 +97,22 @@ public class AppServer {
private final Server server;
private final Connector connector;
private final ServerConnector connector;
private final ContextHandlerCollection contexts;
private final TestRequestLog log;
public AppServer() {
connector = new SelectChannelConnector();
server = new Server();
HttpConfiguration http_config = new HttpConfiguration();
http_config.setSecureScheme("https");
http_config.setSecurePort(8443);
http_config.setOutputBufferSize(32768);
connector = new ServerConnector(server,
new HttpConnectionFactory(http_config));
connector.setPort(0);
try {
final InetAddress me = InetAddress.getByName("localhost");
@ -116,7 +126,6 @@ public AppServer() {
log = new TestRequestLog();
log.setHandler(contexts);
server = new Server();
server.setConnectors(new Connector[] { connector });
server.setHandler(log);
}
@ -173,7 +182,6 @@ protected void loadUsers() throws IOException {
cm.setPathSpec("/*");
ConstraintSecurityHandler sec = new ConstraintSecurityHandler();
sec.setStrict(false);
sec.setRealmName(realm);
sec.setAuthenticator(authType);
sec.setLoginService(users);
@ -232,7 +240,7 @@ public URI getURI() {
/** @return the local port number the server is listening on. */
public int getPort() {
assertAlreadySetUp();
return ((SelectChannelConnector) connector).getLocalPort();
return connector.getLocalPort();
}
/** @return all requests since the server was started. */

View File

@ -187,4 +187,9 @@ public void debug(Throwable thrown) {
public void ignore(Throwable arg0) {
// Ignore (not relevant to test failures)
}
@Override
public void debug(String msg, long value) {
// Ignore (not relevant to test failures)
}
}

View File

@ -48,11 +48,11 @@
import java.util.List;
import java.util.concurrent.Semaphore;
import javax.servlet.DispatcherType;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.server.DispatcherType;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.server.handler.HandlerWrapper;

View File

@ -1,26 +1,26 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?pde?>
<!-- generated with https://github.com/mbarbero/fr.obeo.releng.targetplatform -->
<target name="jgit-4.3" sequenceNumber="1424129720">
<target name="jgit-4.3" sequenceNumber="1431244100">
<locations>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.jetty.client" version="7.6.14.v20131031"/>
<unit id="org.eclipse.jetty.client.source" version="7.6.14.v20131031"/>
<unit id="org.eclipse.jetty.continuation" version="7.6.14.v20131031"/>
<unit id="org.eclipse.jetty.continuation.source" version="7.6.14.v20131031"/>
<unit id="org.eclipse.jetty.http" version="7.6.14.v20131031"/>
<unit id="org.eclipse.jetty.http.source" version="7.6.14.v20131031"/>
<unit id="org.eclipse.jetty.io" version="7.6.14.v20131031"/>
<unit id="org.eclipse.jetty.io.source" version="7.6.14.v20131031"/>
<unit id="org.eclipse.jetty.security" version="7.6.14.v20131031"/>
<unit id="org.eclipse.jetty.security.source" version="7.6.14.v20131031"/>
<unit id="org.eclipse.jetty.server" version="7.6.14.v20131031"/>
<unit id="org.eclipse.jetty.server.source" version="7.6.14.v20131031"/>
<unit id="org.eclipse.jetty.servlet" version="7.6.14.v20131031"/>
<unit id="org.eclipse.jetty.servlet.source" version="7.6.14.v20131031"/>
<unit id="org.eclipse.jetty.util" version="7.6.14.v20131031"/>
<unit id="org.eclipse.jetty.util.source" version="7.6.14.v20131031"/>
<repository id="jetty-7.6.14" location="http://download.eclipse.org/jetty/updates/jetty-bundles-7.x/7.6.14.v20131031/"/>
<unit id="org.eclipse.jetty.client" version="9.2.10.v20150310"/>
<unit id="org.eclipse.jetty.client.source" version="9.2.10.v20150310"/>
<unit id="org.eclipse.jetty.continuation" version="9.2.10.v20150310"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.2.10.v20150310"/>
<unit id="org.eclipse.jetty.http" version="9.2.10.v20150310"/>
<unit id="org.eclipse.jetty.http.source" version="9.2.10.v20150310"/>
<unit id="org.eclipse.jetty.io" version="9.2.10.v20150310"/>
<unit id="org.eclipse.jetty.io.source" version="9.2.10.v20150310"/>
<unit id="org.eclipse.jetty.security" version="9.2.10.v20150310"/>
<unit id="org.eclipse.jetty.security.source" version="9.2.10.v20150310"/>
<unit id="org.eclipse.jetty.server" version="9.2.10.v20150310"/>
<unit id="org.eclipse.jetty.server.source" version="9.2.10.v20150310"/>
<unit id="org.eclipse.jetty.servlet" version="9.2.10.v20150310"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.2.10.v20150310"/>
<unit id="org.eclipse.jetty.util" version="9.2.10.v20150310"/>
<unit id="org.eclipse.jetty.util.source" version="9.2.10.v20150310"/>
<repository id="jetty-9.2.10" location="http://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.2.10.v20150310/"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.apache.ant" version="1.9.2.v201404171502"/>
@ -49,8 +49,8 @@
<unit id="com.jcraft.jsch.source" version="0.1.51.v201410302000"/>
<unit id="org.junit" version="4.11.0.v201303080030"/>
<unit id="org.junit.source" version="4.11.0.v201303080030"/>
<unit id="javax.servlet" version="2.5.0.v201103041518"/>
<unit id="javax.servlet.source" version="2.5.0.v201103041518"/>
<unit id="javax.servlet" version="3.1.0.v20140303-1611"/>
<unit id="javax.servlet.source" version="3.1.0.v20140303-1611"/>
<unit id="org.tukaani.xz" version="1.3.0.v201308270617"/>
<unit id="org.tukaani.xz.source" version="1.3.0.v201308270617"/>
<unit id="org.slf4j.api" version="1.7.2.v20121108-1250"/>

View File

@ -1,6 +1,6 @@
target "jgit-4.3" with source configurePhase
include "projects/jetty-7.6.14.tpd"
include "projects/jetty-9.2.10.tpd"
include "orbit/R20150124073747-Luna-SR2.tpd"
location "http://download.eclipse.org/releases/kepler/" {

View File

@ -1,26 +1,26 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?pde?>
<!-- generated with https://github.com/mbarbero/fr.obeo.releng.targetplatform -->
<target name="jgit-4.4" sequenceNumber="1424129605">
<target name="jgit-4.4" sequenceNumber="1431244089">
<locations>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.jetty.client" version="7.6.14.v20131031"/>
<unit id="org.eclipse.jetty.client.source" version="7.6.14.v20131031"/>
<unit id="org.eclipse.jetty.continuation" version="7.6.14.v20131031"/>
<unit id="org.eclipse.jetty.continuation.source" version="7.6.14.v20131031"/>
<unit id="org.eclipse.jetty.http" version="7.6.14.v20131031"/>
<unit id="org.eclipse.jetty.http.source" version="7.6.14.v20131031"/>
<unit id="org.eclipse.jetty.io" version="7.6.14.v20131031"/>
<unit id="org.eclipse.jetty.io.source" version="7.6.14.v20131031"/>
<unit id="org.eclipse.jetty.security" version="7.6.14.v20131031"/>
<unit id="org.eclipse.jetty.security.source" version="7.6.14.v20131031"/>
<unit id="org.eclipse.jetty.server" version="7.6.14.v20131031"/>
<unit id="org.eclipse.jetty.server.source" version="7.6.14.v20131031"/>
<unit id="org.eclipse.jetty.servlet" version="7.6.14.v20131031"/>
<unit id="org.eclipse.jetty.servlet.source" version="7.6.14.v20131031"/>
<unit id="org.eclipse.jetty.util" version="7.6.14.v20131031"/>
<unit id="org.eclipse.jetty.util.source" version="7.6.14.v20131031"/>
<repository id="jetty-7.6.14" location="http://download.eclipse.org/jetty/updates/jetty-bundles-7.x/7.6.14.v20131031/"/>
<unit id="org.eclipse.jetty.client" version="9.2.10.v20150310"/>
<unit id="org.eclipse.jetty.client.source" version="9.2.10.v20150310"/>
<unit id="org.eclipse.jetty.continuation" version="9.2.10.v20150310"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.2.10.v20150310"/>
<unit id="org.eclipse.jetty.http" version="9.2.10.v20150310"/>
<unit id="org.eclipse.jetty.http.source" version="9.2.10.v20150310"/>
<unit id="org.eclipse.jetty.io" version="9.2.10.v20150310"/>
<unit id="org.eclipse.jetty.io.source" version="9.2.10.v20150310"/>
<unit id="org.eclipse.jetty.security" version="9.2.10.v20150310"/>
<unit id="org.eclipse.jetty.security.source" version="9.2.10.v20150310"/>
<unit id="org.eclipse.jetty.server" version="9.2.10.v20150310"/>
<unit id="org.eclipse.jetty.server.source" version="9.2.10.v20150310"/>
<unit id="org.eclipse.jetty.servlet" version="9.2.10.v20150310"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.2.10.v20150310"/>
<unit id="org.eclipse.jetty.util" version="9.2.10.v20150310"/>
<unit id="org.eclipse.jetty.util.source" version="9.2.10.v20150310"/>
<repository id="jetty-9.2.10" location="http://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.2.10.v20150310/"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.apache.ant" version="1.9.2.v201404171502"/>
@ -49,8 +49,8 @@
<unit id="com.jcraft.jsch.source" version="0.1.51.v201410302000"/>
<unit id="org.junit" version="4.11.0.v201303080030"/>
<unit id="org.junit.source" version="4.11.0.v201303080030"/>
<unit id="javax.servlet" version="2.5.0.v201103041518"/>
<unit id="javax.servlet.source" version="2.5.0.v201103041518"/>
<unit id="javax.servlet" version="3.1.0.v20140303-1611"/>
<unit id="javax.servlet.source" version="3.1.0.v20140303-1611"/>
<unit id="org.tukaani.xz" version="1.3.0.v201308270617"/>
<unit id="org.tukaani.xz.source" version="1.3.0.v201308270617"/>
<unit id="org.slf4j.api" version="1.7.2.v20121108-1250"/>

View File

@ -1,6 +1,6 @@
target "jgit-4.4" with source configurePhase
include "projects/jetty-7.6.14.tpd"
include "projects/jetty-9.2.10.tpd"
include "orbit/R20150124073747-Luna-SR2.tpd"
location "http://download.eclipse.org/releases/luna/" {

View File

@ -1,26 +1,26 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?pde?>
<!-- generated with https://github.com/mbarbero/fr.obeo.releng.targetplatform -->
<target name="jgit-4.5" sequenceNumber="1424129587">
<target name="jgit-4.5" sequenceNumber="1431244072">
<locations>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.eclipse.jetty.client" version="7.6.14.v20131031"/>
<unit id="org.eclipse.jetty.client.source" version="7.6.14.v20131031"/>
<unit id="org.eclipse.jetty.continuation" version="7.6.14.v20131031"/>
<unit id="org.eclipse.jetty.continuation.source" version="7.6.14.v20131031"/>
<unit id="org.eclipse.jetty.http" version="7.6.14.v20131031"/>
<unit id="org.eclipse.jetty.http.source" version="7.6.14.v20131031"/>
<unit id="org.eclipse.jetty.io" version="7.6.14.v20131031"/>
<unit id="org.eclipse.jetty.io.source" version="7.6.14.v20131031"/>
<unit id="org.eclipse.jetty.security" version="7.6.14.v20131031"/>
<unit id="org.eclipse.jetty.security.source" version="7.6.14.v20131031"/>
<unit id="org.eclipse.jetty.server" version="7.6.14.v20131031"/>
<unit id="org.eclipse.jetty.server.source" version="7.6.14.v20131031"/>
<unit id="org.eclipse.jetty.servlet" version="7.6.14.v20131031"/>
<unit id="org.eclipse.jetty.servlet.source" version="7.6.14.v20131031"/>
<unit id="org.eclipse.jetty.util" version="7.6.14.v20131031"/>
<unit id="org.eclipse.jetty.util.source" version="7.6.14.v20131031"/>
<repository id="jetty-7.6.14" location="http://download.eclipse.org/jetty/updates/jetty-bundles-7.x/7.6.14.v20131031/"/>
<unit id="org.eclipse.jetty.client" version="9.2.10.v20150310"/>
<unit id="org.eclipse.jetty.client.source" version="9.2.10.v20150310"/>
<unit id="org.eclipse.jetty.continuation" version="9.2.10.v20150310"/>
<unit id="org.eclipse.jetty.continuation.source" version="9.2.10.v20150310"/>
<unit id="org.eclipse.jetty.http" version="9.2.10.v20150310"/>
<unit id="org.eclipse.jetty.http.source" version="9.2.10.v20150310"/>
<unit id="org.eclipse.jetty.io" version="9.2.10.v20150310"/>
<unit id="org.eclipse.jetty.io.source" version="9.2.10.v20150310"/>
<unit id="org.eclipse.jetty.security" version="9.2.10.v20150310"/>
<unit id="org.eclipse.jetty.security.source" version="9.2.10.v20150310"/>
<unit id="org.eclipse.jetty.server" version="9.2.10.v20150310"/>
<unit id="org.eclipse.jetty.server.source" version="9.2.10.v20150310"/>
<unit id="org.eclipse.jetty.servlet" version="9.2.10.v20150310"/>
<unit id="org.eclipse.jetty.servlet.source" version="9.2.10.v20150310"/>
<unit id="org.eclipse.jetty.util" version="9.2.10.v20150310"/>
<unit id="org.eclipse.jetty.util.source" version="9.2.10.v20150310"/>
<repository id="jetty-9.2.10" location="http://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.2.10.v20150310/"/>
</location>
<location includeMode="slicer" includeAllPlatforms="false" includeSource="true" includeConfigurePhase="true" type="InstallableUnit">
<unit id="org.apache.ant" version="1.9.4.v201410062020"/>
@ -49,8 +49,8 @@
<unit id="com.jcraft.jsch.source" version="0.1.51.v201410302000"/>
<unit id="org.junit" version="4.11.0.v201303080030"/>
<unit id="org.junit.source" version="4.11.0.v201303080030"/>
<unit id="javax.servlet" version="2.5.0.v201103041518"/>
<unit id="javax.servlet.source" version="2.5.0.v201103041518"/>
<unit id="javax.servlet" version="3.1.0.v201410161800"/>
<unit id="javax.servlet.source" version="3.1.0.v201410161800"/>
<unit id="org.tukaani.xz" version="1.3.0.v201308270617"/>
<unit id="org.tukaani.xz.source" version="1.3.0.v201308270617"/>
<unit id="org.slf4j.api" version="1.7.2.v20121108-1250"/>

View File

@ -1,6 +1,6 @@
target "jgit-4.5" with source configurePhase
include "projects/jetty-7.6.14.tpd"
include "projects/jetty-9.2.10.tpd"
include "orbit/S20150202203538-Mars-M5.tpd"
location "http://download.eclipse.org/releases/mars/" {

View File

@ -28,8 +28,8 @@ location "http://download.eclipse.org/tools/orbit/downloads/drops/R2015012407374
com.jcraft.jsch.source [0.1.51.v201410302000,0.1.51.v201410302000]
org.junit [4.11.0.v201303080030,4.11.0.v201303080030]
org.junit.source [4.11.0.v201303080030,4.11.0.v201303080030]
javax.servlet [2.5.0.v201103041518,2.5.0.v201103041518]
javax.servlet.source [2.5.0.v201103041518,2.5.0.v201103041518]
javax.servlet [3.1.0.v20140303-1611,3.1.0.v20140303-1611]
javax.servlet.source [3.1.0.v20140303-1611,3.1.0.v20140303-1611]
org.tukaani.xz [1.3.0.v201308270617,1.3.0.v201308270617]
org.tukaani.xz.source [1.3.0.v201308270617,1.3.0.v201308270617]
org.slf4j.api [1.7.2.v20121108-1250,1.7.2.v20121108-1250]

View File

@ -28,8 +28,8 @@ location "http://download.eclipse.org/tools/orbit/downloads/drops/S2015020220353
com.jcraft.jsch.source [0.1.51.v201410302000,0.1.51.v201410302000]
org.junit [4.11.0.v201303080030,4.11.0.v201303080030]
org.junit.source [4.11.0.v201303080030,4.11.0.v201303080030]
javax.servlet [2.5.0.v201103041518,2.5.0.v201103041518]
javax.servlet.source [2.5.0.v201103041518,2.5.0.v201103041518]
javax.servlet [3.1.0.v201410161800,3.1.0.v201410161800]
javax.servlet.source [3.1.0.v201410161800,3.1.0.v201410161800]
org.tukaani.xz [1.3.0.v201308270617,1.3.0.v201308270617]
org.tukaani.xz.source [1.3.0.v201308270617,1.3.0.v201308270617]
org.slf4j.api [1.7.2.v20121108-1250,1.7.2.v20121108-1250]

View File

@ -1,20 +0,0 @@
target "jetty-7.6.14" with source configurePhase
location jetty-7.6.14 "http://download.eclipse.org/jetty/updates/jetty-bundles-7.x/7.6.14.v20131031/" {
org.eclipse.jetty.client [7.6.14.v20131031,7.6.14.v20131031]
org.eclipse.jetty.client.source [7.6.14.v20131031,7.6.14.v20131031]
org.eclipse.jetty.continuation [7.6.14.v20131031,7.6.14.v20131031]
org.eclipse.jetty.continuation.source [7.6.14.v20131031,7.6.14.v20131031]
org.eclipse.jetty.http [7.6.14.v20131031,7.6.14.v20131031]
org.eclipse.jetty.http.source [7.6.14.v20131031,7.6.14.v20131031]
org.eclipse.jetty.io [7.6.14.v20131031,7.6.14.v20131031]
org.eclipse.jetty.io.source [7.6.14.v20131031,7.6.14.v20131031]
org.eclipse.jetty.security [7.6.14.v20131031,7.6.14.v20131031]
org.eclipse.jetty.security.source [7.6.14.v20131031,7.6.14.v20131031]
org.eclipse.jetty.server [7.6.14.v20131031,7.6.14.v20131031]
org.eclipse.jetty.server.source [7.6.14.v20131031,7.6.14.v20131031]
org.eclipse.jetty.servlet [7.6.14.v20131031,7.6.14.v20131031]
org.eclipse.jetty.servlet.source [7.6.14.v20131031,7.6.14.v20131031]
org.eclipse.jetty.util [7.6.14.v20131031,7.6.14.v20131031]
org.eclipse.jetty.util.source [7.6.14.v20131031,7.6.14.v20131031]
}

View File

@ -0,0 +1,20 @@
target "jetty-9.2.10" with source configurePhase
location jetty-9.2.10 "http://download.eclipse.org/jetty/updates/jetty-bundles-9.x/9.2.10.v20150310/" {
org.eclipse.jetty.client [9.2.10.v20150310,9.2.10.v20150310]
org.eclipse.jetty.client.source [9.2.10.v20150310,9.2.10.v20150310]
org.eclipse.jetty.continuation [9.2.10.v20150310,9.2.10.v20150310]
org.eclipse.jetty.continuation.source [9.2.10.v20150310,9.2.10.v20150310]
org.eclipse.jetty.http [9.2.10.v20150310,9.2.10.v20150310]
org.eclipse.jetty.http.source [9.2.10.v20150310,9.2.10.v20150310]
org.eclipse.jetty.io [9.2.10.v20150310,9.2.10.v20150310]
org.eclipse.jetty.io.source [9.2.10.v20150310,9.2.10.v20150310]
org.eclipse.jetty.security [9.2.10.v20150310,9.2.10.v20150310]
org.eclipse.jetty.security.source [9.2.10.v20150310,9.2.10.v20150310]
org.eclipse.jetty.server [9.2.10.v20150310,9.2.10.v20150310]
org.eclipse.jetty.server.source [9.2.10.v20150310,9.2.10.v20150310]
org.eclipse.jetty.servlet [9.2.10.v20150310,9.2.10.v20150310]
org.eclipse.jetty.servlet.source [9.2.10.v20150310,9.2.10.v20150310]
org.eclipse.jetty.util [9.2.10.v20150310,9.2.10.v20150310]
org.eclipse.jetty.util.source [9.2.10.v20150310,9.2.10.v20150310]
}

View File

@ -267,6 +267,7 @@ protected void show(final RevCommit c) throws Exception {
outw.print(s);
outw.println();
}
c.disposeBody();
outw.println();
if (showNotes(c))

View File

@ -51,9 +51,6 @@
/**
* Tests git attributes pattern matches
* <p>
* Inspired by {@link org.eclipse.jgit.ignore.IgnoreMatcherTest}
* </p>
*/
public class AttributesMatcherTest {

View File

@ -47,30 +47,11 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.junit.Assume.assumeFalse;
import static org.junit.Assume.assumeTrue;
import java.util.Arrays;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;
@SuppressWarnings("deprecation")
@RunWith(Parameterized.class)
public class FastIgnoreRuleTest {
@Parameters(name = "OldRule? {0}")
public static Iterable<Boolean[]> data() {
return Arrays.asList(new Boolean[][] { { Boolean.FALSE },
{ Boolean.TRUE } });
}
@Parameter
public Boolean useOldRule;
@Test
public void testSimpleCharClass() {
assertMatched("[a]", "a");
@ -385,58 +366,46 @@ public void testSegmentsDoNotMatch() {
assertNotMatched("a/b/", "c/a/b/c");
}
@SuppressWarnings("boxing")
@Test
public void testWildmatch() {
if (useOldRule)
System.err
.println("IgnoreRule can't understand wildmatch rules, skipping testWildmatch!");
assertMatched("**/a/b", "a/b");
assertMatched("**/a/b", "c/a/b");
assertMatched("**/a/b", "c/d/a/b");
assertMatched("**/**/a/b", "c/d/a/b");
Boolean assume = useOldRule;
assertMatched("**/a/b", "a/b", assume);
assertMatched("**/a/b", "c/a/b", assume);
assertMatched("**/a/b", "c/d/a/b", assume);
assertMatched("**/**/a/b", "c/d/a/b", assume);
assertMatched("/**/a/b", "a/b");
assertMatched("/**/a/b", "c/a/b");
assertMatched("/**/a/b", "c/d/a/b");
assertMatched("/**/**/a/b", "c/d/a/b");
assertMatched("/**/a/b", "a/b", assume);
assertMatched("/**/a/b", "c/a/b", assume);
assertMatched("/**/a/b", "c/d/a/b", assume);
assertMatched("/**/**/a/b", "c/d/a/b", assume);
assertMatched("a/b/**", "a/b");
assertMatched("a/b/**", "a/b/c");
assertMatched("a/b/**", "a/b/c/d/");
assertMatched("a/b/**/**", "a/b/c/d");
assertMatched("a/b/**", "a/b", assume);
assertMatched("a/b/**", "a/b/c", assume);
assertMatched("a/b/**", "a/b/c/d/", assume);
assertMatched("a/b/**/**", "a/b/c/d", assume);
assertMatched("**/a/**/b", "c/d/a/b");
assertMatched("**/a/**/b", "c/d/a/e/b");
assertMatched("**/**/a/**/**/b", "c/d/a/e/b");
assertMatched("**/a/**/b", "c/d/a/b", assume);
assertMatched("**/a/**/b", "c/d/a/e/b", assume);
assertMatched("**/**/a/**/**/b", "c/d/a/e/b", assume);
assertMatched("/**/a/**/b", "c/d/a/b");
assertMatched("/**/a/**/b", "c/d/a/e/b");
assertMatched("/**/**/a/**/**/b", "c/d/a/e/b");
assertMatched("/**/a/**/b", "c/d/a/b", assume);
assertMatched("/**/a/**/b", "c/d/a/e/b", assume);
assertMatched("/**/**/a/**/**/b", "c/d/a/e/b", assume);
assertMatched("a/**/b", "a/b");
assertMatched("a/**/b", "a/c/b");
assertMatched("a/**/b", "a/c/d/b");
assertMatched("a/**/**/b", "a/c/d/b");
assertMatched("a/**/b", "a/b", assume);
assertMatched("a/**/b", "a/c/b", assume);
assertMatched("a/**/b", "a/c/d/b", assume);
assertMatched("a/**/**/b", "a/c/d/b", assume);
assertMatched("a/**/b/**/c", "a/c/b/d/c", assume);
assertMatched("a/**/**/b/**/**/c", "a/c/b/d/c", assume);
assertMatched("a/**/b/**/c", "a/c/b/d/c");
assertMatched("a/**/**/b/**/**/c", "a/c/b/d/c");
}
@SuppressWarnings("boxing")
@Test
public void testWildmatchDoNotMatch() {
if (useOldRule)
System.err
.println("IgnoreRule can't understand wildmatch rules, skipping testWildmatchDoNotMatch!");
Boolean assume = useOldRule;
assertNotMatched("**/a/b", "a/c/b", assume);
assertNotMatched("!/**/*.zip", "c/a/b.zip", assume);
assertNotMatched("!**/*.zip", "c/a/b.zip", assume);
assertNotMatched("a/**/b", "a/c/bb", assume);
assertNotMatched("**/a/b", "a/c/b");
assertNotMatched("!/**/*.zip", "c/a/b.zip");
assertNotMatched("!**/*.zip", "c/a/b.zip");
assertNotMatched("a/**/b", "a/c/bb");
}
@SuppressWarnings("unused")
@ -478,55 +447,43 @@ public void testSplit() {
split("/a/b/c/", '/').toArray());
}
public void assertMatched(String pattern, String path, Boolean... assume) {
public void assertMatched(String pattern, String path) {
boolean match = match(pattern, path);
String result = path + " is " + (match ? "ignored" : "not ignored")
+ " via '" + pattern + "' rule";
if (!match)
if (!match) {
System.err.println(result);
if (assume.length == 0 || !assume[0].booleanValue())
assertTrue("Expected a match for: " + pattern + " with: " + path,
match);
else
assumeTrue("Expected a match for: " + pattern + " with: " + path,
}
assertTrue("Expected a match for: " + pattern + " with: " + path,
match);
if (pattern.startsWith("!"))
if (pattern.startsWith("!")) {
pattern = pattern.substring(1);
else
} else {
pattern = "!" + pattern;
}
match = match(pattern, path);
if (assume.length == 0 || !assume[0].booleanValue())
assertFalse("Expected no match for: " + pattern + " with: " + path,
match);
else
assumeFalse("Expected no match for: " + pattern + " with: " + path,
match);
assertFalse("Expected no match for: " + pattern + " with: " + path,
match);
}
public void assertNotMatched(String pattern, String path, Boolean... assume) {
public void assertNotMatched(String pattern, String path) {
boolean match = match(pattern, path);
String result = path + " is " + (match ? "ignored" : "not ignored")
+ " via '" + pattern + "' rule";
if (match)
if (match) {
System.err.println(result);
if (assume.length == 0 || !assume[0].booleanValue())
assertFalse("Expected no match for: " + pattern + " with: " + path,
match);
else
assumeFalse("Expected no match for: " + pattern + " with: " + path,
}
assertFalse("Expected no match for: " + pattern + " with: " + path,
match);
if (pattern.startsWith("!"))
if (pattern.startsWith("!")) {
pattern = pattern.substring(1);
else
} else {
pattern = "!" + pattern;
}
match = match(pattern, path);
if (assume.length == 0 || !assume[0].booleanValue())
assertTrue("Expected a match for: " + pattern + " with: " + path,
match);
else
assumeTrue("Expected a match for: " + pattern + " with: " + path,
assertTrue("Expected a match for: " + pattern + " with: " + path,
match);
}
@ -542,16 +499,6 @@ public void assertNotMatched(String pattern, String path, Boolean... assume) {
*/
private boolean match(String pattern, String target) {
boolean isDirectory = target.endsWith("/");
if (useOldRule.booleanValue()) {
IgnoreRule r = new IgnoreRule(pattern);
// If speed of this test is ever an issue, we can use a presetRule
// field
// to avoid recompiling a pattern each time.
boolean match = r.isMatch(target, isDirectory);
if (r.getNegation())
match = !match;
return match;
}
FastIgnoreRule r = new FastIgnoreRule(pattern);
// If speed of this test is ever an issue, we can use a presetRule field
// to avoid recompiling a pattern each time.

View File

@ -47,31 +47,14 @@
import static org.junit.Assume.assumeFalse;
import static org.junit.Assume.assumeTrue;
import java.util.Arrays;
import org.eclipse.jgit.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;
/**
* Tests ignore pattern matches
*/
@SuppressWarnings("deprecation")
@RunWith(Parameterized.class)
public class IgnoreMatcherParametrizedTest {
@Parameters(name = "OldRule? {0}")
public static Iterable<Boolean[]> data() {
return Arrays.asList(new Boolean[][] { { Boolean.FALSE },
{ Boolean.TRUE } });
}
@Parameter
public Boolean useOldRule;
@Test
public void testBasic() {
String pattern = "/test.stp";
@ -252,47 +235,38 @@ public void testDirModeAndNoRegex() {
@Test
public void testDirModeAndRegex1() {
// IgnoreRule was buggy for some cases below, therefore using "Assume"
Boolean assume = useOldRule;
String pattern = "a/*/src/";
assertMatched(pattern, "a/b/src/");
assertMatched(pattern, "a/b/src/new");
assertMatched(pattern, "a/b/src/new/a.c");
assertMatched(pattern, "a/b/src/a.c");
// no match as a "file" pattern, because rule is for directories only
assertNotMatched(pattern, "a/b/src", assume);
assertNotMatched(pattern, "a/b/src");
assertNotMatched(pattern, "a/b/srcA/");
}
@Test
public void testDirModeAndRegex2() {
// IgnoreRule was buggy for some cases below, therefore using "Assume"
Boolean assume = useOldRule;
String pattern = "a/[a-b]/src/";
assertMatched(pattern, "a/b/src/");
assertMatched(pattern, "a/b/src/new");
assertMatched(pattern, "a/b/src/new/a.c");
assertMatched(pattern, "a/b/src/a.c");
// no match as a "file" pattern, because rule is for directories only
assertNotMatched(pattern, "a/b/src", assume);
assertNotMatched(pattern, "a/b/src");
assertNotMatched(pattern, "a/b/srcA/");
}
@Test
public void testDirModeAndRegex3() {
// IgnoreRule was buggy for some cases below, therefore using "Assume"
Boolean assume = useOldRule;
String pattern = "**/src/";
assertMatched(pattern, "a/b/src/", assume);
assertMatched(pattern, "a/b/src/new", assume);
assertMatched(pattern, "a/b/src/new/a.c", assume);
assertMatched(pattern, "a/b/src/a.c", assume);
assertMatched(pattern, "a/b/src/");
assertMatched(pattern, "a/b/src/new");
assertMatched(pattern, "a/b/src/new/a.c");
assertMatched(pattern, "a/b/src/a.c");
// no match as a "file" pattern, because rule is for directories only
assertNotMatched(pattern, "a/b/src", assume);
assertNotMatched(pattern, "a/b/srcA/", assume);
assertNotMatched(pattern, "a/b/src");
assertNotMatched(pattern, "a/b/srcA/");
}
@Test
@ -416,13 +390,8 @@ public void assertNotMatched(String pattern, String target,
private boolean match(String pattern, String target) {
boolean isDirectory = target.endsWith("/");
boolean match;
if (useOldRule.booleanValue()) {
IgnoreRule r = new IgnoreRule(pattern);
match = r.isMatch(target, isDirectory);
} else {
FastIgnoreRule r = new FastIgnoreRule(pattern);
match = r.isMatch(target, isDirectory);
}
FastIgnoreRule r = new FastIgnoreRule(pattern);
match = r.isMatch(target, isDirectory);
if (isDirectory) {
boolean noTrailingSlash = matchAsDir(pattern,
@ -447,10 +416,6 @@ private boolean match(String pattern, String target) {
*/
private boolean matchAsDir(String pattern, String target) {
assertFalse(target.endsWith("/"));
if (useOldRule.booleanValue()) {
IgnoreRule r = new IgnoreRule(pattern);
return r.isMatch(target, true);
}
FastIgnoreRule r = new FastIgnoreRule(pattern);
return r.isMatch(target, true);
}

View File

@ -1,400 +0,0 @@
/*
* Copyright (C) 2010, Red Hat 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.ignore;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
/**
* Tests ignore pattern matches
*/
@SuppressWarnings("deprecation")
public class IgnoreMatcherTest {
@Test
public void testBasic() {
String pattern = "/test.stp";
assertMatched(pattern, "/test.stp");
pattern = "#/test.stp";
assertNotMatched(pattern, "/test.stp");
}
@Test
public void testFileNameWildcards() {
//Test basic * and ? for any pattern + any character
String pattern = "*.st?";
assertMatched(pattern, "/test.stp");
assertMatched(pattern, "/anothertest.stg");
assertMatched(pattern, "/anothertest.st0");
assertNotMatched(pattern, "/anothertest.sta1");
//Check that asterisk does not expand to "/"
assertNotMatched(pattern, "/another/test.sta1");
//Same as above, with a leading slash to ensure that doesn't cause problems
pattern = "/*.st?";
assertMatched(pattern, "/test.stp");
assertMatched(pattern, "/anothertest.stg");
assertMatched(pattern, "/anothertest.st0");
assertNotMatched(pattern, "/anothertest.sta1");
//Check that asterisk does not expand to "/"
assertNotMatched(pattern, "/another/test.sta1");
//Test for numbers
pattern = "*.sta[0-5]";
assertMatched(pattern, "/test.sta5");
assertMatched(pattern, "/test.sta4");
assertMatched(pattern, "/test.sta3");
assertMatched(pattern, "/test.sta2");
assertMatched(pattern, "/test.sta1");
assertMatched(pattern, "/test.sta0");
assertMatched(pattern, "/anothertest.sta2");
assertNotMatched(pattern, "test.stag");
assertNotMatched(pattern, "test.sta6");
//Test for letters
pattern = "/[tv]est.sta[a-d]";
assertMatched(pattern, "/test.staa");
assertMatched(pattern, "/test.stab");
assertMatched(pattern, "/test.stac");
assertMatched(pattern, "/test.stad");
assertMatched(pattern, "/vest.stac");
assertNotMatched(pattern, "test.stae");
assertNotMatched(pattern, "test.sta9");
//Test child directory/file is matched
pattern = "/src/ne?";
assertMatched(pattern, "/src/new/");
assertMatched(pattern, "/src/new");
assertMatched(pattern, "/src/new/a.c");
assertMatched(pattern, "/src/new/a/a.c");
assertNotMatched(pattern, "/src/new.c");
//Test name-only fnmatcher matches
pattern = "ne?";
assertMatched(pattern, "/src/new/");
assertMatched(pattern, "/src/new");
assertMatched(pattern, "/src/new/a.c");
assertMatched(pattern, "/src/new/a/a.c");
assertMatched(pattern, "/neb");
assertNotMatched(pattern, "/src/new.c");
}
@Test
public void testTargetWithoutLeadingSlash() {
//Test basic * and ? for any pattern + any character
String pattern = "/*.st?";
assertMatched(pattern, "test.stp");
assertMatched(pattern, "anothertest.stg");
assertMatched(pattern, "anothertest.st0");
assertNotMatched(pattern, "anothertest.sta1");
//Check that asterisk does not expand to ""
assertNotMatched(pattern, "another/test.sta1");
//Same as above, with a leading slash to ensure that doesn't cause problems
pattern = "/*.st?";
assertMatched(pattern, "test.stp");
assertMatched(pattern, "anothertest.stg");
assertMatched(pattern, "anothertest.st0");
assertNotMatched(pattern, "anothertest.sta1");
//Check that asterisk does not expand to ""
assertNotMatched(pattern, "another/test.sta1");
//Test for numbers
pattern = "/*.sta[0-5]";
assertMatched(pattern, "test.sta5");
assertMatched(pattern, "test.sta4");
assertMatched(pattern, "test.sta3");
assertMatched(pattern, "test.sta2");
assertMatched(pattern, "test.sta1");
assertMatched(pattern, "test.sta0");
assertMatched(pattern, "anothertest.sta2");
assertNotMatched(pattern, "test.stag");
assertNotMatched(pattern, "test.sta6");
//Test for letters
pattern = "/[tv]est.sta[a-d]";
assertMatched(pattern, "test.staa");
assertMatched(pattern, "test.stab");
assertMatched(pattern, "test.stac");
assertMatched(pattern, "test.stad");
assertMatched(pattern, "vest.stac");
assertNotMatched(pattern, "test.stae");
assertNotMatched(pattern, "test.sta9");
//Test child directory/file is matched
pattern = "/src/ne?";
assertMatched(pattern, "src/new/");
assertMatched(pattern, "src/new");
assertMatched(pattern, "src/new/a.c");
assertMatched(pattern, "src/new/a/a.c");
assertNotMatched(pattern, "src/new.c");
//Test name-only fnmatcher matches
pattern = "ne?";
assertMatched(pattern, "src/new/");
assertMatched(pattern, "src/new");
assertMatched(pattern, "src/new/a.c");
assertMatched(pattern, "src/new/a/a.c");
assertMatched(pattern, "neb");
assertNotMatched(pattern, "src/new.c");
}
@Test
public void testParentDirectoryGitIgnores() {
//Contains git ignore patterns such as might be seen in a parent directory
//Test for wildcards
String pattern = "/*/*.c";
assertMatched(pattern, "/file/a.c");
assertMatched(pattern, "/src/a.c");
assertNotMatched(pattern, "/src/new/a.c");
//Test child directory/file is matched
pattern = "/src/new";
assertMatched(pattern, "/src/new/");
assertMatched(pattern, "/src/new");
assertMatched(pattern, "/src/new/a.c");
assertMatched(pattern, "/src/new/a/a.c");
assertNotMatched(pattern, "/src/new.c");
//Test child directory is matched, slash after name
pattern = "/src/new/";
assertMatched(pattern, "/src/new/");
assertMatched(pattern, "/src/new/a.c");
assertMatched(pattern, "/src/new/a/a.c");
assertNotMatched(pattern, "/src/new");
assertNotMatched(pattern, "/src/new.c");
//Test directory is matched by name only
pattern = "b1";
assertMatched(pattern, "/src/new/a/b1/a.c");
assertNotMatched(pattern, "/src/new/a/b2/file.c");
assertNotMatched(pattern, "/src/new/a/bb1/file.c");
assertNotMatched(pattern, "/src/new/a/file.c");
}
@Test
public void testTrailingSlash() {
String pattern = "/src/";
assertMatched(pattern, "/src/");
assertMatched(pattern, "/src/new");
assertMatched(pattern, "/src/new/a.c");
assertMatched(pattern, "/src/a.c");
assertNotMatched(pattern, "/src");
assertNotMatched(pattern, "/srcA/");
}
@Test
public void testNameOnlyMatches() {
/*
* Name-only matches do not contain any path separators
*/
//Test matches for file extension
String pattern = "*.stp";
assertMatched(pattern, "/test.stp");
assertMatched(pattern, "/src/test.stp");
assertNotMatched(pattern, "/test.stp1");
assertNotMatched(pattern, "/test.astp");
//Test matches for name-only, applies to file name or folder name
pattern = "src";
assertMatched(pattern, "/src");
assertMatched(pattern, "/src/");
assertMatched(pattern, "/src/a.c");
assertMatched(pattern, "/src/new/a.c");
assertMatched(pattern, "/new/src/a.c");
assertMatched(pattern, "/file/src");
//Test matches for name-only, applies only to folder names
pattern = "src/";
assertMatched(pattern, "/src/");
assertMatched(pattern, "/src/a.c");
assertMatched(pattern, "/src/new/a.c");
assertMatched(pattern, "/new/src/a.c");
assertNotMatched(pattern, "/src");
assertNotMatched(pattern, "/file/src");
//Test matches for name-only, applies to file name or folder name
//With a small wildcard
pattern = "?rc";
assertMatched(pattern, "/src/a.c");
assertMatched(pattern, "/src/new/a.c");
assertMatched(pattern, "/new/src/a.c");
assertMatched(pattern, "/file/src");
assertMatched(pattern, "/src/");
//Test matches for name-only, applies to file name or folder name
//With a small wildcard
pattern = "?r[a-c]";
assertMatched(pattern, "/src/a.c");
assertMatched(pattern, "/src/new/a.c");
assertMatched(pattern, "/new/src/a.c");
assertMatched(pattern, "/file/src");
assertMatched(pattern, "/src/");
assertMatched(pattern, "/srb/a.c");
assertMatched(pattern, "/grb/new/a.c");
assertMatched(pattern, "/new/crb/a.c");
assertMatched(pattern, "/file/3rb");
assertMatched(pattern, "/xrb/");
assertMatched(pattern, "/3ra/a.c");
assertMatched(pattern, "/5ra/new/a.c");
assertMatched(pattern, "/new/1ra/a.c");
assertMatched(pattern, "/file/dra");
assertMatched(pattern, "/era/");
assertNotMatched(pattern, "/crg");
assertNotMatched(pattern, "/cr3");
}
@Test
public void testNegation() {
String pattern = "!/test.stp";
assertMatched(pattern, "/test.stp");
}
@Test
public void testGetters() {
IgnoreRule r = new IgnoreRule("/pattern/");
assertFalse(r.getNameOnly());
assertTrue(r.dirOnly());
assertFalse(r.getNegation());
assertEquals(r.getPattern(), "/pattern");
r = new IgnoreRule("/patter?/");
assertFalse(r.getNameOnly());
assertTrue(r.dirOnly());
assertFalse(r.getNegation());
assertEquals(r.getPattern(), "/patter?");
r = new IgnoreRule("patt*");
assertTrue(r.getNameOnly());
assertFalse(r.dirOnly());
assertFalse(r.getNegation());
assertEquals(r.getPattern(), "patt*");
r = new IgnoreRule("pattern");
assertTrue(r.getNameOnly());
assertFalse(r.dirOnly());
assertFalse(r.getNegation());
assertEquals(r.getPattern(), "pattern");
r = new IgnoreRule("!pattern");
assertTrue(r.getNameOnly());
assertFalse(r.dirOnly());
assertTrue(r.getNegation());
assertEquals(r.getPattern(), "pattern");
r = new IgnoreRule("!/pattern");
assertFalse(r.getNameOnly());
assertFalse(r.dirOnly());
assertTrue(r.getNegation());
assertEquals(r.getPattern(), "/pattern");
r = new IgnoreRule("!/patter?");
assertFalse(r.getNameOnly());
assertFalse(r.dirOnly());
assertTrue(r.getNegation());
assertEquals(r.getPattern(), "/patter?");
}
@Test
public void testResetState() {
String pattern = "/build/*";
String target = "/build";
// Don't use the assert methods of this class, as we want to test
// whether the state in IgnoreRule is reset properly
IgnoreRule r = new IgnoreRule(pattern);
// Result should be the same for the same inputs
assertFalse(r.isMatch(target, true));
assertFalse(r.isMatch(target, true));
}
/**
* Check for a match. If target ends with "/", match will assume that the
* target is meant to be a directory.
* @param pattern
* Pattern as it would appear in a .gitignore file
* @param target
* Target file path relative to repository's GIT_DIR
*/
public void assertMatched(String pattern, String target) {
boolean value = match(pattern, target);
assertTrue("Expected a match for: " + pattern + " with: " + target,
value);
}
/**
* Check for a match. If target ends with "/", match will assume that the
* target is meant to be a directory.
* @param pattern
* Pattern as it would appear in a .gitignore file
* @param target
* Target file path relative to repository's GIT_DIR
*/
public void assertNotMatched(String pattern, String target) {
boolean value = match(pattern, target);
assertFalse("Expected no match for: " + pattern + " with: " + target,
value);
}
/**
* Check for a match. If target ends with "/", match will assume that the
* target is meant to be a directory.
*
* @param pattern
* Pattern as it would appear in a .gitignore file
* @param target
* Target file path relative to repository's GIT_DIR
* @return Result of IgnoreRule.isMatch(String, boolean)
*/
private static boolean match(String pattern, String target) {
IgnoreRule r = new IgnoreRule(pattern);
//If speed of this test is ever an issue, we can use a presetRule field
//to avoid recompiling a pattern each time.
return r.isMatch(target, target.endsWith("/"));
}
}

View File

@ -46,64 +46,32 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assume.assumeTrue;
import java.util.Arrays;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;
@RunWith(Parameterized.class)
@SuppressWarnings({ "deprecation", "boxing" })
@SuppressWarnings({ "boxing" })
public class IgnoreRuleSpecialCasesTest {
@Parameters(name = "OldRule? {0}")
public static Iterable<Boolean[]> data() {
return Arrays.asList(new Boolean[][] { { Boolean.FALSE },
{ Boolean.TRUE } });
}
@Parameter
public Boolean useOldRule;
private void assertMatch(final String pattern, final String input,
final boolean matchExpected, Boolean... assume) {
boolean assumeDir = input.endsWith("/");
if (useOldRule.booleanValue()) {
final IgnoreRule matcher = new IgnoreRule(pattern);
if (assume.length == 0 || !assume[0].booleanValue())
assertEquals(matchExpected, matcher.isMatch(input, assumeDir));
else
assumeTrue(matchExpected == matcher.isMatch(input, assumeDir));
FastIgnoreRule matcher = new FastIgnoreRule(pattern);
if (assume.length == 0 || !assume[0].booleanValue()) {
assertEquals(matchExpected, matcher.isMatch(input, assumeDir));
} else {
FastIgnoreRule matcher = new FastIgnoreRule(pattern);
if (assume.length == 0 || !assume[0].booleanValue())
assertEquals(matchExpected, matcher.isMatch(input, assumeDir));
else
assumeTrue(matchExpected == matcher.isMatch(input, assumeDir));
assumeTrue(matchExpected == matcher.isMatch(input, assumeDir));
}
}
private void assertFileNameMatch(final String pattern, final String input,
final boolean matchExpected) {
boolean assumeDir = input.endsWith("/");
if (useOldRule.booleanValue()) {
final IgnoreRule matcher = new IgnoreRule(pattern);
assertEquals(matchExpected, matcher.isMatch(input, assumeDir));
} else {
FastIgnoreRule matcher = new FastIgnoreRule(pattern);
assertEquals(matchExpected, matcher.isMatch(input, assumeDir));
}
FastIgnoreRule matcher = new FastIgnoreRule(pattern);
assertEquals(matchExpected, matcher.isMatch(input, assumeDir));
}
@Test
public void testVerySimplePatternCase0() throws Exception {
if (useOldRule)
System.err
.println("IgnoreRule can't understand blank lines, skipping");
Boolean assume = useOldRule;
assertMatch("", "", false, assume);
assertMatch("", "", false);
}
@Test
@ -805,12 +773,9 @@ public void testSpecialGroupCase9() throws Exception {
@Test
public void testSpecialGroupCase10() throws Exception {
if (useOldRule)
System.err.println("IgnoreRule can't understand [[:], skipping");
Boolean assume = useOldRule;
// Second bracket is threated literally, so both [ and : should match
assertMatch("[[:]", ":", true, assume);
assertMatch("[[:]", "[", true, assume);
assertMatch("[[:]", ":", true);
assertMatch("[[:]", "[", true);
}
@Test
@ -866,12 +831,8 @@ public void testEscapedBracket6() throws Exception {
@Test
public void testEscapedBackslash() throws Exception {
if (useOldRule)
System.err
.println("IgnoreRule can't understand escaped backslashes, skipping");
Boolean assume = useOldRule;
// In Git CLI a\\b matches a\b file
assertMatch("a\\\\b", "a\\b", true, assume);
assertMatch("a\\\\b", "a\\b", true);
}
@Test

View File

@ -0,0 +1,152 @@
/*
* Copyright (C) 2015, Google Inc.
* and other copyright owners as documented in the project's IP log.
*
* This program and the accompanying materials are made available
* under the terms of the Eclipse Distribution License v1.0 which
* accompanies this distribution, is reproduced below, and is
* available at http://www.eclipse.org/org/documents/edl-v10.php
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* - Neither the name of the Eclipse Foundation, Inc. nor the
* names of its contributors may be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.eclipse.jgit.internal.storage.dfs;
import static org.eclipse.jgit.lib.Constants.OBJ_BLOB;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import org.eclipse.jgit.internal.storage.dfs.DeltaBaseCache.Entry;
import org.eclipse.jgit.junit.TestRng;
import org.junit.Before;
import org.junit.Test;
public class DeltaBaseCacheTest {
private static final int SZ = 512;
private DfsPackKey key;
private DeltaBaseCache cache;
private TestRng rng;
@Before
public void setUp() {
key = new DfsPackKey();
cache = new DeltaBaseCache(SZ);
rng = new TestRng(getClass().getSimpleName());
}
@Test
public void testObjectLargerThanCacheDoesNotEvict() {
byte[] obj12 = put(12, 32);
put(24, SZ + 5);
assertNull("does not store large object", cache.get(key, 24));
get(obj12, 12);
}
@Test
public void testCacheLruExpires1() {
byte[] obj1 = put(1, SZ / 4);
put(2, SZ / 4);
byte[] obj3 = put(3, SZ / 4);
put(4, SZ / 4);
assertEquals(SZ, cache.getMemoryUsed());
get(obj3, 3);
get(obj1, 1);
put(5, SZ / 2);
assertEquals(SZ, cache.getMemoryUsed());
assertEquals(SZ, cache.getMemoryUsedByTableForTest());
assertEquals(SZ, cache.getMemoryUsedByLruChainForTest());
assertNull(cache.get(key, 4));
assertNull(cache.get(key, 2));
get(obj1, 1);
get(obj3, 3);
}
@Test
public void testCacheLruExpires2() {
int pos0 = (0 << 10) | 2;
int pos1 = (1 << 10) | 2;
int pos2 = (2 << 10) | 2;
int pos5 = (5 << 10) | 2;
int pos6 = (6 << 10) | 2;
put(pos0, SZ / 4);
put(pos5, SZ / 4);
byte[] obj1 = put(pos1, SZ / 4);
byte[] obj2 = put(pos2, SZ / 4);
assertEquals(SZ, cache.getMemoryUsed());
byte[] obj6 = put(pos6, SZ / 2);
assertEquals(SZ, cache.getMemoryUsed());
assertEquals(SZ, cache.getMemoryUsedByTableForTest());
assertEquals(SZ, cache.getMemoryUsedByLruChainForTest());
assertNull(cache.get(key, pos0));
assertNull(cache.get(key, pos5));
get(obj1, pos1);
get(obj2, pos2);
get(obj6, pos6);
}
@Test
public void testCacheMemoryUsedConsistentWithExpectations() {
put(1, 32);
put(2, 32);
put(3, 32);
assertNotNull(cache.get(key, 1));
assertNotNull(cache.get(key, 1));
assertEquals(32 * 3, cache.getMemoryUsed());
assertEquals(32 * 3, cache.getMemoryUsedByTableForTest());
assertEquals(32 * 3, cache.getMemoryUsedByLruChainForTest());
}
private void get(byte[] data, int position) {
Entry e = cache.get(key, position);
assertNotNull("expected entry at " + position, e);
assertEquals("expected blob for " + position, OBJ_BLOB, e.type);
assertSame("expected data for " + position, data, e.data);
}
private byte[] put(int position, int sz) {
byte[] data = rng.nextBytes(sz);
cache.put(key, position, OBJ_BLOB, data);
return data;
}
}

View File

@ -360,10 +360,10 @@ private RevCommit parse(final String msg) throws IOException {
buf.append("\n");
buf.append(msg);
final RevWalk walk = new RevWalk(db);
walk.setRetainBody(true);
final RevCommit c = new RevCommit(ObjectId.zeroId());
c.parseCanonical(walk, Constants.encode(buf.toString()));
return c;
try (RevWalk walk = new RevWalk(db)) {
RevCommit c = new RevCommit(ObjectId.zeroId());
c.parseCanonical(walk, Constants.encode(buf.toString()));
return c;
}
}
}

View File

@ -46,15 +46,10 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeFalse;
import static org.junit.Assume.assumeNotNull;
import static org.junit.Assume.assumeTrue;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.attribute.PosixFileAttributeView;
import java.nio.file.attribute.PosixFilePermission;
@ -123,29 +118,15 @@ public void testSymlinkAttributes() throws IOException, InterruptedException {
@Test
public void testExecutableAttributes() throws Exception {
FS fs = FS.DETECTED;
FS fs = FS.DETECTED.newInstance();
// If this assumption fails the test is halted and ignored.
assumeTrue(fs instanceof FS_POSIX);
((FS_POSIX) fs).setUmask(0022);
File f = new File(trash, "bla");
assertTrue(f.createNewFile());
assertFalse(fs.canExecute(f));
String umask = readUmask();
assumeNotNull(umask);
char others = umask.charAt(umask.length() - 1);
boolean badUmask;
if (others != '0' && others != '2' && others != '4' && others != '6') {
// umask is set in the way that "others" can not "execute" => git
// CLI will not set "execute" attribute for "others", so we also
// don't care
badUmask = true;
} else {
badUmask = false;
}
Set<PosixFilePermission> permissions = readPermissions(f);
assertTrue(!permissions.contains(PosixFilePermission.OTHERS_EXECUTE));
assertTrue(!permissions.contains(PosixFilePermission.GROUP_EXECUTE));
@ -158,27 +139,21 @@ public void testExecutableAttributes() throws Exception {
permissions.contains(PosixFilePermission.OWNER_EXECUTE));
assertTrue("'group' execute permission not set",
permissions.contains(PosixFilePermission.GROUP_EXECUTE));
if (badUmask) {
assertFalse("'others' execute permission set",
permissions.contains(PosixFilePermission.OTHERS_EXECUTE));
System.err.println("WARNING: your system's umask: \"" + umask
+ "\" doesn't allow FSJava7Test to test if setting posix"
+ " permissions for \"others\" works properly");
assumeFalse(badUmask);
} else {
assertTrue("'others' execute permission not set",
permissions.contains(PosixFilePermission.OTHERS_EXECUTE));
}
}
assertTrue("'others' execute permission not set",
permissions.contains(PosixFilePermission.OTHERS_EXECUTE));
private String readUmask() throws Exception {
Process p = Runtime.getRuntime().exec(
new String[] { "sh", "-c", "umask" }, null, null);
final BufferedReader lineRead = new BufferedReader(
new InputStreamReader(p.getInputStream(), Charset
.defaultCharset().name()));
p.waitFor();
return lineRead.readLine();
((FS_POSIX) fs).setUmask(0033);
fs.setExecute(f, false);
assertFalse(fs.canExecute(f));
fs.setExecute(f, true);
permissions = readPermissions(f);
assertTrue("'owner' execute permission not set",
permissions.contains(PosixFilePermission.OWNER_EXECUTE));
assertFalse("'group' execute permission set",
permissions.contains(PosixFilePermission.GROUP_EXECUTE));
assertFalse("'others' execute permission set",
permissions.contains(PosixFilePermission.OTHERS_EXECUTE));
}
private Set<PosixFilePermission> readPermissions(File f) throws IOException {

View File

@ -57,7 +57,9 @@ Export-Package: org.eclipse.jgit.api;version="4.0.0";
org.eclipse.jgit.ignore;version="4.0.0",
org.eclipse.jgit.ignore.internal;version="4.0.0";x-friends:="org.eclipse.jgit.test",
org.eclipse.jgit.internal;version="4.0.0";x-friends:="org.eclipse.jgit.test,org.eclipse.jgit.http.test",
org.eclipse.jgit.internal.storage.dfs;version="4.0.0";x-friends:="org.eclipse.jgit.test",
org.eclipse.jgit.internal.storage.dfs;version="4.0.0";
x-friends:="org.eclipse.jgit.test,
org.eclipse.jgit.http.server",
org.eclipse.jgit.internal.storage.file;version="4.0.0";
x-friends:="org.eclipse.jgit.test,
org.eclipse.jgit.junit,

View File

@ -1227,7 +1227,7 @@ private RevCommit tryFastForward(String headName, RevCommit oldCommit,
RefUpdate rup = repo.updateRef(headName);
rup.setExpectedOldObjectId(oldCommit);
rup.setNewObjectId(newCommit);
rup.setRefLogMessage("Fast-foward from " + oldCommit.name() //$NON-NLS-1$
rup.setRefLogMessage("Fast-forward from " + oldCommit.name() //$NON-NLS-1$
+ " to " + newCommit.name(), false); //$NON-NLS-1$
Result res = rup.update(walk);
switch (res) {

View File

@ -188,7 +188,6 @@ public StashCreateCommand setIncludeUntracked(boolean includeUntracked) {
private RevCommit parseCommit(final ObjectReader reader,
final ObjectId headId) throws IOException {
final RevWalk walk = new RevWalk(reader);
walk.setRetainBody(true);
return walk.parseCommit(headId);
}

View File

@ -96,10 +96,8 @@ public Collection<RevCommit> call() throws GitAPIException,
final List<RevCommit> stashCommits = new ArrayList<RevCommit>(
stashEntries.size());
final RevWalk walk = new RevWalk(repo);
walk.setRetainBody(true);
try {
for (ReflogEntry entry : stashEntries)
try (RevWalk walk = new RevWalk(repo)) {
for (ReflogEntry entry : stashEntries) {
try {
stashCommits.add(walk.parseCommit(entry.getNewId()));
} catch (IOException e) {
@ -107,8 +105,7 @@ public Collection<RevCommit> call() throws GitAPIException,
JGitText.get().cannotReadCommit, entry.getNewId()),
e);
}
} finally {
walk.dispose();
}
}
return stashCommits;
}

View File

@ -179,7 +179,6 @@ private void initRevPool(boolean reverse) {
else
revPool = new RevWalk(getRepository());
revPool.setRetainBody(true);
SEEN = revPool.newFlag("SEEN"); //$NON-NLS-1$
reader = revPool.getObjectReader();
treeWalk = new TreeWalk(reader);

View File

@ -1129,73 +1129,6 @@ private boolean isModifiedSubtree_IndexTree(String path, ObjectId tree)
}
}
/**
* Updates the file in the working tree with content and mode from an entry
* in the index. The new content is first written to a new temporary file in
* the same directory as the real file. Then that new file is renamed to the
* final filename. Use this method only for checkout of a single entry.
* Otherwise use
* {@code checkoutEntry(Repository, File f, DirCacheEntry, ObjectReader)}
* instead which allows to reuse one {@code ObjectReader} for multiple
* entries.
*
* <p>
* TODO: this method works directly on File IO, we may need another
* abstraction (like WorkingTreeIterator). This way we could tell e.g.
* Eclipse that Files in the workspace got changed
* </p>
*
* @param repository
* @param f
* this parameter is ignored.
* @param entry
* the entry containing new mode and content
* @throws IOException
* @deprecated Use the overloaded form that accepts {@link ObjectReader}.
*/
@Deprecated
public static void checkoutEntry(final Repository repository, File f,
DirCacheEntry entry) throws IOException {
ObjectReader or = repository.newObjectReader();
try {
checkoutEntry(repository, f, entry, or);
} finally {
or.release();
}
}
/**
* Updates the file in the working tree with content and mode from an entry
* in the index. The new content is first written to a new temporary file in
* the same directory as the real file. Then that new file is renamed to the
* final filename.
*
* <p>
* TODO: this method works directly on File IO, we may need another
* abstraction (like WorkingTreeIterator). This way we could tell e.g.
* Eclipse that Files in the workspace got changed
* </p>
*
* @param repo
* @param f
* this parameter is ignored.
* @param entry
* the entry containing new mode and content
* @param or
* object reader to use for checkout
* @throws IOException
* @deprecated Do not pass File object.
*/
@Deprecated
public static void checkoutEntry(final Repository repo, File f,
DirCacheEntry entry, ObjectReader or) throws IOException {
if (f == null || repo.getWorkTree() == null)
throw new IllegalArgumentException();
if (!f.equals(new File(repo.getWorkTree(), entry.getPathString())))
throw new IllegalArgumentException();
checkoutEntry(repo, entry, or);
}
/**
* Updates the file in the working tree with content and mode from an entry
* in the index. The new content is first written to a new temporary file in

View File

@ -399,7 +399,7 @@ final boolean contains(final byte[] a, int aOff, final int aLen) {
for (int eOff = 0; eOff < eLen && aOff < aLen; eOff++, aOff++)
if (e[eOff] != a[aOff])
return false;
if (aOff == aLen)
if (aOff >= aLen)
return false;
return a[aOff] == '/';
}

View File

@ -114,9 +114,9 @@ final class GroupHead extends AbstractHead {
characterClasses.add(LetterPattern.INSTANCE);
characterClasses.add(DigitPattern.INSTANCE);
} else {
final String message = String.format(MessageFormat.format(
final String message = MessageFormat.format(
JGitText.get().characterClassIsNotSupported,
characterClass));
characterClass);
throw new InvalidPatternException(message, wholePattern);
}

View File

@ -1,278 +0,0 @@
/*
* Copyright (C) 2010, Red Hat 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.ignore;
import org.eclipse.jgit.errors.InvalidPatternException;
import org.eclipse.jgit.fnmatch.FileNameMatcher;
/**
* A single ignore rule corresponding to one line in a .gitignore or ignore
* file. Parses the ignore pattern
*
* Inspiration from: Ferry Huberts
*
* @deprecated this rule does not support double star pattern and is slow
* parsing glob expressions. Consider to use {@link FastIgnoreRule}
* instead. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=440732
*/
@Deprecated
public class IgnoreRule {
private String pattern;
private boolean negation;
private boolean nameOnly;
private boolean dirOnly;
private FileNameMatcher matcher;
/**
* Create a new ignore rule with the given pattern. Assumes that
* the pattern is already trimmed.
*
* @param pattern
* Base pattern for the ignore rule. This pattern will
* be parsed to generate rule parameters.
*/
public IgnoreRule (String pattern) {
this.pattern = pattern;
negation = false;
nameOnly = false;
dirOnly = false;
matcher = null;
setup();
}
/**
* Remove leading/trailing characters as needed. Set up
* rule variables for later matching.
*/
private void setup() {
int startIndex = 0;
int endIndex = pattern.length();
if (pattern.startsWith("!")) { //$NON-NLS-1$
startIndex++;
negation = true;
}
if (pattern.endsWith("/")) { //$NON-NLS-1$
endIndex --;
dirOnly = true;
}
pattern = pattern.substring(startIndex, endIndex);
boolean hasSlash = pattern.contains("/"); //$NON-NLS-1$
if (!hasSlash)
nameOnly = true;
else if (!pattern.startsWith("/")) { //$NON-NLS-1$
//Contains "/" but does not start with one
//Adding / to the start should not interfere with matching
pattern = "/" + pattern; //$NON-NLS-1$
}
if (pattern.contains("*") || pattern.contains("?") || pattern.contains("[")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
try {
matcher = new FileNameMatcher(pattern, Character.valueOf('/'));
} catch (InvalidPatternException e) {
// Ignore pattern exceptions
}
}
}
/**
* @return
* True if the pattern is just a file name and not a path
*/
public boolean getNameOnly() {
return nameOnly;
}
/**
*
* @return
* True if the pattern should match directories only
*/
public boolean dirOnly() {
return dirOnly;
}
/**
*
* @return
* True if the pattern had a "!" in front of it
*/
public boolean getNegation() {
return negation;
}
/**
* @return
* The blob pattern to be used as a matcher
*/
public String getPattern() {
return pattern;
}
/**
* Returns true if a match was made.
* <br>
* This function does NOT return the actual ignore status of the
* target! Please consult {@link #getResult()} for the ignore status. The actual
* ignore status may be true or false depending on whether this rule is
* an ignore rule or a negation rule.
*
* @param target
* Name pattern of the file, relative to the base directory of this rule
* @param isDirectory
* Whether the target file is a directory or not
* @return
* True if a match was made. This does not necessarily mean that
* the target is ignored. Call {@link IgnoreRule#getResult() getResult()} for the result.
*/
public boolean isMatch(String target, boolean isDirectory) {
if (!target.startsWith("/")) //$NON-NLS-1$
target = "/" + target; //$NON-NLS-1$
if (matcher == null) {
if (target.equals(pattern)) {
//Exact match
if (dirOnly && !isDirectory)
//Directory expectations not met
return false;
else
//Directory expectations met
return true;
}
/*
* Add slashes for startsWith check. This avoids matching e.g.
* "/src/new" to /src/newfile" but allows "/src/new" to match
* "/src/new/newfile", as is the git standard
*/
if ((target).startsWith(pattern + "/")) //$NON-NLS-1$
return true;
if (nameOnly) {
//Iterate through each sub-name
final String[] segments = target.split("/"); //$NON-NLS-1$
for (int idx = 0; idx < segments.length; idx++) {
final String segmentName = segments[idx];
// String.split("/") creates empty segment for leading slash
if (segmentName.length() == 0)
continue;
if (segmentName.equals(pattern) &&
doesMatchDirectoryExpectations(isDirectory, idx, segments.length))
return true;
}
}
} else {
matcher.reset();
matcher.append(target);
if (matcher.isMatch())
return true;
final String[] segments = target.split("/"); //$NON-NLS-1$
if (nameOnly) {
for (int idx = 0; idx < segments.length; idx++) {
final String segmentName = segments[idx];
// String.split("/") creates empty segment for leading slash
if (segmentName.length() == 0)
continue;
//Iterate through each sub-directory
matcher.reset();
matcher.append(segmentName);
if (matcher.isMatch() &&
doesMatchDirectoryExpectations(isDirectory, idx, segments.length))
return true;
}
} else {
//TODO: This is the slowest operation
//This matches e.g. "/src/ne?" to "/src/new/file.c"
matcher.reset();
for (int idx = 0; idx < segments.length; idx++) {
final String segmentName = segments[idx];
// String.split("/") creates empty segment for leading slash
if (segmentName.length() == 0)
continue;
matcher.append("/" + segmentName); //$NON-NLS-1$
if (matcher.isMatch()
&& doesMatchDirectoryExpectations(isDirectory, idx,
segments.length))
return true;
}
}
}
return false;
}
/**
* If a call to <code>isMatch(String, boolean)</code> was previously
* made, this will return whether or not the target was ignored. Otherwise
* this just indicates whether the rule is non-negation or negation.
*
* @return
* True if the target is to be ignored, false otherwise.
*/
public boolean getResult() {
return !negation;
}
private boolean doesMatchDirectoryExpectations(boolean isDirectory, int segmentIdx, int segmentLength) {
// The segment we are checking is a directory, expectations are met.
if (segmentIdx < segmentLength - 1) {
return true;
}
// We are checking the last part of the segment for which isDirectory has to be considered.
return !dirOnly || isDirectory;
}
@Override
public String toString() {
return pattern;
}
}

View File

@ -43,7 +43,6 @@
package org.eclipse.jgit.internal.storage.dfs;
import java.lang.ref.SoftReference;
/**
* Caches recently used objects for {@link DfsReader}.
@ -60,30 +59,28 @@ private static int hash(long position) {
}
private int maxByteCount;
private final Slot[] table;
private Slot lruHead;
private Slot lruTail;
private int curByteCount;
private final Entry[] table;
private Entry lruHead;
private Entry lruTail;
DeltaBaseCache(DfsReader reader) {
DfsReaderOptions options = reader.getOptions();
maxByteCount = options.getDeltaBaseCacheLimit();
table = new Slot[1 << TABLE_BITS];
this(reader.getOptions().getDeltaBaseCacheLimit());
}
DeltaBaseCache(int maxBytes) {
maxByteCount = maxBytes;
table = new Entry[1 << TABLE_BITS];
}
Entry get(DfsPackKey key, long position) {
Slot e = table[hash(position)];
Entry e = table[hash(position)];
for (; e != null; e = e.tableNext) {
if (e.offset == position && key.equals(e.pack)) {
Entry buf = e.data.get();
if (buf != null) {
moveToHead(e);
return buf;
}
moveToHead(e);
return e;
}
}
return null;
@ -97,33 +94,24 @@ void put(DfsPackKey key, long offset, int objectType, byte[] data) {
releaseMemory();
int tableIdx = hash(offset);
Slot e = new Slot(key, offset, data.length);
e.data = new SoftReference<Entry>(new Entry(data, objectType));
Entry e = new Entry(key, offset, objectType, data);
e.tableNext = table[tableIdx];
table[tableIdx] = e;
moveToHead(e);
lruPushHead(e);
}
private void releaseMemory() {
while (curByteCount > maxByteCount && lruTail != null) {
Slot currOldest = lruTail;
Slot nextOldest = currOldest.lruPrev;
curByteCount -= currOldest.size;
unlink(currOldest);
removeFromTable(currOldest);
if (nextOldest == null)
lruHead = null;
else
nextOldest.lruNext = null;
lruTail = nextOldest;
Entry e = lruTail;
curByteCount -= e.data.length;
lruRemove(e);
removeFromTable(e);
}
}
private void removeFromTable(Slot e) {
private void removeFromTable(Entry e) {
int tableIdx = hash(e.offset);
Slot p = table[tableIdx];
Entry p = table[tableIdx];
if (p == e) {
table[tableIdx] = e.tableNext;
@ -136,59 +124,85 @@ private void removeFromTable(Slot e) {
return;
}
}
throw new IllegalStateException(String.format(
"entry for %s:%d not in table", //$NON-NLS-1$
e.pack, Long.valueOf(e.offset)));
}
private void moveToHead(final Slot e) {
unlink(e);
e.lruPrev = null;
e.lruNext = lruHead;
if (lruHead != null)
lruHead.lruPrev = e;
private void moveToHead(Entry e) {
if (e != lruHead) {
lruRemove(e);
lruPushHead(e);
}
}
private void lruRemove(Entry e) {
Entry p = e.lruPrev;
Entry n = e.lruNext;
if (p != null) {
p.lruNext = n;
} else {
lruHead = n;
}
if (n != null) {
n.lruPrev = p;
} else {
lruTail = p;
}
}
private void lruPushHead(Entry e) {
Entry n = lruHead;
e.lruNext = n;
if (n != null)
n.lruPrev = e;
else
lruTail = e;
e.lruPrev = null;
lruHead = e;
}
private void unlink(final Slot e) {
Slot prev = e.lruPrev;
Slot next = e.lruNext;
int getMemoryUsed() {
return curByteCount;
}
if (prev != null)
prev.lruNext = next;
if (next != null)
next.lruPrev = prev;
int getMemoryUsedByLruChainForTest() {
int r = 0;
for (Entry e = lruHead; e != null; e = e.lruNext) {
r += e.data.length;
}
return r;
}
int getMemoryUsedByTableForTest() {
int r = 0;
for (int i = 0; i < table.length; i++) {
for (Entry e = table[i]; e != null; e = e.tableNext) {
r += e.data.length;
}
}
return r;
}
static class Entry {
final DfsPackKey pack;
final long offset;
final int type;
final byte[] data;
final int type;
Entry tableNext;
Entry lruPrev;
Entry lruNext;
Entry(final byte[] aData, final int aType) {
data = aData;
type = aType;
}
}
private static class Slot {
final DfsPackKey pack;
final long offset;
final int size;
Slot tableNext;
Slot lruPrev;
Slot lruNext;
SoftReference<Entry> data;
Slot(DfsPackKey key, long offset, int size) {
Entry(DfsPackKey key, long offset, int type, byte[] data) {
this.pack = key;
this.offset = offset;
this.size = size;
this.type = type;
this.data = data;
}
}
}

View File

@ -255,8 +255,13 @@ public static String format(byte[] delta, boolean includeHeader) {
shift += 7;
} while ((c & 0x80) != 0);
if (includeHeader)
r.append("DELTA( BASE=" + baseLen + " RESULT=" + resLen + " )\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
if (includeHeader) {
r.append("DELTA( BASE="); //$NON-NLS-1$
r.append(baseLen);
r.append(" RESULT="); //$NON-NLS-1$
r.append(resLen);
r.append(" )\n"); //$NON-NLS-1$
}
while (deltaPtr < delta.length) {
final int cmd = delta[deltaPtr++] & 0xff;
@ -285,8 +290,11 @@ public static String format(byte[] delta, boolean includeHeader) {
if (copySize == 0)
copySize = 0x10000;
r.append(" COPY (" + copyOffset + ", " + copySize + ")\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
r.append(" COPY ("); //$NON-NLS-1$
r.append(copyOffset);
r.append(", "); //$NON-NLS-1$
r.append(copySize);
r.append(")\n"); //$NON-NLS-1$
} else if (cmd != 0) {
// Anything else the data is literal within the delta
// itself.

View File

@ -390,15 +390,15 @@ public String toString() {
if (isEdge())
buf.append(" edge");
if (getDeltaDepth() > 0)
buf.append(" depth=" + getDeltaDepth());
buf.append(" depth=").append(getDeltaDepth());
if (isDeltaRepresentation()) {
if (getDeltaBase() != null)
buf.append(" base=inpack:" + getDeltaBase().name());
buf.append(" base=inpack:").append(getDeltaBase().name());
else
buf.append(" base=edge:" + getDeltaBaseId().name());
buf.append(" base=edge:").append(getDeltaBaseId().name());
}
if (isWritten())
buf.append(" offset=" + getOffset());
buf.append(" offset=").append(getOffset());
buf.append("]");
return buf.toString();
}

View File

@ -136,8 +136,8 @@
* Typical usage consists of creating instance intended for some pack,
* configuring options, preparing the list of objects by calling
* {@link #preparePack(Iterator)} or
* {@link #preparePack(ProgressMonitor, Collection, Collection)}, and finally
* producing the stream with
* {@link #preparePack(ProgressMonitor, Set, Set)}, and finally producing the
* stream with
* {@link #writePack(ProgressMonitor, ProgressMonitor, OutputStream)}.
* </p>
* <p>
@ -293,7 +293,7 @@ public static Iterable<PackWriter> getInstances() {
* Create writer for specified repository.
* <p>
* Objects for packing are specified in {@link #preparePack(Iterator)} or
* {@link #preparePack(ProgressMonitor, Collection, Collection)}.
* {@link #preparePack(ProgressMonitor, Set, Set)}.
*
* @param repo
* repository where objects are stored.
@ -306,7 +306,7 @@ public PackWriter(final Repository repo) {
* Create a writer to load objects from the specified reader.
* <p>
* Objects for packing are specified in {@link #preparePack(Iterator)} or
* {@link #preparePack(ProgressMonitor, Collection, Collection)}.
* {@link #preparePack(ProgressMonitor, Set, Set)}.
*
* @param reader
* reader to read from the repository with.
@ -319,7 +319,7 @@ public PackWriter(final ObjectReader reader) {
* Create writer for specified repository.
* <p>
* Objects for packing are specified in {@link #preparePack(Iterator)} or
* {@link #preparePack(ProgressMonitor, Collection, Collection)}.
* {@link #preparePack(ProgressMonitor, Set, Set)}.
*
* @param repo
* repository where objects are stored.
@ -334,7 +334,7 @@ public PackWriter(final Repository repo, final ObjectReader reader) {
* Create writer with a specified configuration.
* <p>
* Objects for packing are specified in {@link #preparePack(Iterator)} or
* {@link #preparePack(ProgressMonitor, Collection, Collection)}.
* {@link #preparePack(ProgressMonitor, Set, Set)}.
*
* @param config
* configuration for the pack writer.
@ -495,7 +495,7 @@ public void setIndexDisabled(boolean noIndex) {
/**
* @return true to ignore objects that are uninteresting and also not found
* on local disk; false to throw a {@link MissingObjectException}
* out of {@link #preparePack(ProgressMonitor, Collection, Collection)} if an
* out of {@link #preparePack(ProgressMonitor, Set, Set)} if an
* uninteresting object is not in the source repository. By default,
* true, permitting gracefully ignoring of uninteresting objects.
*/
@ -648,86 +648,6 @@ public void preparePack(final Iterator<RevObject> objectsSource)
}
}
/**
* Prepare the list of objects to be written to the pack stream.
* <p>
* Basing on these 2 sets, another set of objects to put in a pack file is
* created: this set consists of all objects reachable (ancestors) from
* interesting objects, except uninteresting objects and their ancestors.
* This method uses class {@link ObjectWalk} extensively to find out that
* appropriate set of output objects and their optimal order in output pack.
* Order is consistent with general git in-pack rules: sort by object type,
* recency, path and delta-base first.
* </p>
*
* @param countingMonitor
* progress during object enumeration.
* @param want
* collection of objects to be marked as interesting (start
* points of graph traversal).
* @param have
* collection of objects to be marked as uninteresting (end
* points of graph traversal).
* @throws IOException
* when some I/O problem occur during reading objects.
* @deprecated to be removed in 2.0; use the Set version of this method.
*/
@Deprecated
public void preparePack(ProgressMonitor countingMonitor,
final Collection<? extends ObjectId> want,
final Collection<? extends ObjectId> have) throws IOException {
preparePack(countingMonitor, ensureSet(want), ensureSet(have));
}
/**
* Prepare the list of objects to be written to the pack stream.
* <p>
* Basing on these 2 sets, another set of objects to put in a pack file is
* created: this set consists of all objects reachable (ancestors) from
* interesting objects, except uninteresting objects and their ancestors.
* This method uses class {@link ObjectWalk} extensively to find out that
* appropriate set of output objects and their optimal order in output pack.
* Order is consistent with general git in-pack rules: sort by object type,
* recency, path and delta-base first.
* </p>
*
* @param countingMonitor
* progress during object enumeration.
* @param walk
* ObjectWalk to perform enumeration.
* @param interestingObjects
* collection of objects to be marked as interesting (start
* points of graph traversal).
* @param uninterestingObjects
* collection of objects to be marked as uninteresting (end
* points of graph traversal).
* @throws IOException
* when some I/O problem occur during reading objects.
* @deprecated to be removed in 2.0; use the Set version of this method.
*/
@Deprecated
public void preparePack(ProgressMonitor countingMonitor,
ObjectWalk walk,
final Collection<? extends ObjectId> interestingObjects,
final Collection<? extends ObjectId> uninterestingObjects)
throws IOException {
preparePack(countingMonitor, walk,
ensureSet(interestingObjects),
ensureSet(uninterestingObjects));
}
@SuppressWarnings("unchecked")
private static Set<ObjectId> ensureSet(Collection<? extends ObjectId> objs) {
Set<ObjectId> set;
if (objs instanceof Set<?>)
set = (Set<ObjectId>) objs;
else if (objs == null)
set = Collections.emptySet();
else
set = new HashSet<ObjectId>(objs);
return set;
}
/**
* Prepare the list of objects to be written to the pack stream.
* <p>
@ -1667,8 +1587,6 @@ private void findObjectsToPack(final ProgressMonitor countingMonitor,
stats.interestingObjects = Collections.unmodifiableSet(new HashSet<ObjectId>(want));
stats.uninterestingObjects = Collections.unmodifiableSet(new HashSet<ObjectId>(have));
walker.setRetainBody(false);
canBuildBitmaps = config.isBuildBitmaps()
&& !shallowPack
&& have.isEmpty()

View File

@ -53,9 +53,6 @@
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.internal.storage.pack.ObjectReuseAsIs;
import org.eclipse.jgit.revwalk.ObjectWalk;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
/**
* Reads an {@link ObjectDatabase} for a single thread.
@ -398,44 +395,6 @@ public void release() {
};
}
/**
* Advice from a {@link RevWalk} that a walk is starting from these roots.
*
* @param walk
* the revision pool that is using this reader.
* @param roots
* starting points of the revision walk. The starting points have
* their headers parsed, but might be missing bodies.
* @throws IOException
* the reader cannot initialize itself to support the walk.
*/
public void walkAdviceBeginCommits(RevWalk walk, Collection<RevCommit> roots)
throws IOException {
// Do nothing by default, most readers don't want or need advice.
}
/**
* Advice from an {@link ObjectWalk} that trees will be traversed.
*
* @param ow
* the object pool that is using this reader.
* @param min
* the first commit whose root tree will be read.
* @param max
* the last commit whose root tree will be read.
* @throws IOException
* the reader cannot initialize itself to support the walk.
*/
public void walkAdviceBeginTrees(ObjectWalk ow, RevCommit min, RevCommit max)
throws IOException {
// Do nothing by default, most readers don't want or need advice.
}
/** Advice from that a walk is over. */
public void walkAdviceEnd() {
// Do nothing by default, most readers don't want or need advice.
}
/**
* Advise the reader to avoid unreachable objects.
* <p>

View File

@ -90,6 +90,7 @@
import org.eclipse.jgit.treewalk.NameConflictTreeWalk;
import org.eclipse.jgit.treewalk.TreeWalk;
import org.eclipse.jgit.treewalk.WorkingTreeIterator;
import org.eclipse.jgit.treewalk.filter.TreeFilter;
import org.eclipse.jgit.util.FS;
import org.eclipse.jgit.util.TemporaryBuffer;
@ -1012,8 +1013,11 @@ protected boolean mergeTrees(AbstractTreeIterator baseTree,
tw.addTree(headTree);
tw.addTree(mergeTree);
tw.addTree(buildIt);
if (workingTreeIterator != null)
if (workingTreeIterator != null) {
tw.addTree(workingTreeIterator);
} else {
tw.setFilter(TreeFilter.ANY_DIFF);
}
if (!mergeTreeWalk(tw, ignoreConflicts)) {
return false;

View File

@ -137,7 +137,6 @@ RevCommit next() throws MissingObjectException,
for (;;) {
final RevCommit c = pending.next();
if (c == null) {
walker.reader.walkAdviceEnd();
return null;
}

View File

@ -60,6 +60,7 @@
import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.ObjectReader;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.filter.ObjectFilter;
import org.eclipse.jgit.util.RawParseUtils;
/**
@ -99,9 +100,7 @@ public class ObjectWalk extends RevWalk {
private BlockObjQueue pendingObjects;
private RevCommit firstCommit;
private RevCommit lastCommit;
private ObjectFilter objectFilter;
private TreeVisit freeVisit;
@ -133,8 +132,10 @@ public ObjectWalk(final Repository repo) {
*/
public ObjectWalk(ObjectReader or) {
super(or);
setRetainBody(false);
rootObjects = new ArrayList<RevObject>();
pendingObjects = new BlockObjQueue();
objectFilter = ObjectFilter.ALL;
pathBuf = new byte[256];
}
@ -253,26 +254,59 @@ public void sort(RevSort s, boolean use) {
boundary = hasRevSort(RevSort.BOUNDARY);
}
/**
* Get the currently configured object filter.
*
* @return the current filter. Never null as a filter is always needed.
*
* @since 4.0
*/
public ObjectFilter getObjectFilter() {
return objectFilter;
}
/**
* Set the object filter for this walker. This filter affects the objects
* visited by {@link #nextObject()}. It does not affect the commits
* listed by {@link #next()}.
* <p>
* If the filter returns false for an object, then that object is skipped
* and objects reachable from it are not enqueued to be walked recursively.
* This can be used to speed up the object walk by skipping subtrees that
* are known to be uninteresting.
*
* @param newFilter
* the new filter. If null the special {@link ObjectFilter#ALL}
* filter will be used instead, as it matches every object.
*
* @since 4.0
*/
public void setObjectFilter(ObjectFilter newFilter) {
assertNotStarted();
objectFilter = newFilter != null ? newFilter : ObjectFilter.ALL;
}
@Override
public RevCommit next() throws MissingObjectException,
IncorrectObjectTypeException, IOException {
for (;;) {
final RevCommit r = super.next();
if (r == null) {
if (firstCommit != null)
reader.walkAdviceBeginTrees(this, firstCommit, lastCommit);
return null;
}
final RevTree t = r.getTree();
if ((r.flags & UNINTERESTING) != 0) {
markTreeUninteresting(r.getTree());
if (boundary)
if (objectFilter.include(this, t)) {
markTreeUninteresting(t);
}
if (boundary) {
return r;
}
continue;
}
if (firstCommit == null)
firstCommit = r;
lastCommit = r;
pendingObjects.add(r.getTree());
if (objectFilter.include(this, t)) {
pendingObjects.add(t);
}
return r;
}
}
@ -304,6 +338,10 @@ public RevObject nextObject() throws MissingObjectException,
idBuffer.fromRaw(buf, ptr);
ptr += ID_SZ;
if (!objectFilter.include(this, idBuffer)) {
continue;
}
RevObject obj = objects.get(idBuffer);
if (obj != null && (obj.flags & SEEN) != 0)
continue;
@ -365,7 +403,6 @@ public RevObject nextObject() throws MissingObjectException,
for (;;) {
RevObject o = pendingObjects.next();
if (o == null) {
reader.walkAdviceEnd();
return null;
}
int flags = o.flags;
@ -633,8 +670,6 @@ private void growPathBuf(int ptr) {
public void dispose() {
super.dispose();
pendingObjects = new BlockObjQueue();
firstCommit = null;
lastCommit = null;
currVisit = null;
freeVisit = null;
}
@ -648,8 +683,6 @@ protected void reset(final int retainFlags) {
rootObjects = new ArrayList<RevObject>();
pendingObjects = new BlockObjQueue();
firstCommit = null;
lastCommit = null;
currVisit = null;
freeVisit = null;
}

View File

@ -128,7 +128,6 @@ RevCommit next() throws MissingObjectException,
for (;;) {
final RevCommit c = pending.next();
if (c == null) {
walker.reader.walkAdviceEnd();
return null;
}
@ -177,7 +176,6 @@ else if (canDispose)
c.disposeBody();
}
} catch (StopWalkException swe) {
walker.reader.walkAdviceEnd();
pending.clear();
return null;
}

View File

@ -92,29 +92,34 @@ public static RevCommit parse(byte[] raw) {
/**
* Parse a commit from its canonical format.
*
* <p>
* This method inserts the commit directly into the caller supplied revision
* pool, making it appear as though the commit exists in the repository,
* even if it doesn't. The repository under the pool is not affected.
* <p>
* The body of the commit (message, author, committer) is always retained in
* the returned {@code RevCommit}, even if the supplied {@code RevWalk} has
* been configured with {@code setRetainBody(false)}.
*
* @param rw
* the revision pool to allocate the commit within. The commit's
* tree and parent pointers will be obtained from this pool.
* @param raw
* the canonical formatted commit to be parsed.
* the canonical formatted commit to be parsed. This buffer will
* be retained by the returned {@code RevCommit} and must not be
* modified by the caller.
* @return the parsed commit, in an isolated revision pool that is not
* available to the caller.
* @throws IOException
* in case of RevWalk initialization fails
*/
public static RevCommit parse(RevWalk rw, byte[] raw) throws IOException {
ObjectInserter.Formatter fmt = new ObjectInserter.Formatter();
boolean retain = rw.isRetainBody();
rw.setRetainBody(true);
RevCommit r = rw.lookupCommit(fmt.idFor(Constants.OBJ_COMMIT, raw));
r.parseCanonical(rw, raw);
rw.setRetainBody(retain);
return r;
try (ObjectInserter.Formatter fmt = new ObjectInserter.Formatter()) {
RevCommit r = rw.lookupCommit(fmt.idFor(Constants.OBJ_COMMIT, raw));
r.parseCanonical(rw, raw);
r.buffer = raw;
return r;
}
}
static final RevCommit[] NO_PARENTS = {};
@ -604,7 +609,19 @@ public void reset() {
inDegree = 0;
}
final void disposeBody() {
/**
* Discard the message buffer to reduce memory usage.
* <p>
* After discarding the memory usage of the {@code RevCommit} is reduced to
* only the {@link #getTree()} and {@link #getParents()} pointers and the
* time in {@link #getCommitTime()}. Accessing other properties such as
* {@link #getAuthorIdent()}, {@link #getCommitterIdent()} or either message
* function requires reloading the buffer by invoking
* {@link RevWalk#parseBody(RevObject)}.
*
* @since 4.0
*/
public final void disposeBody() {
buffer = null;
}

View File

@ -87,16 +87,22 @@ public static RevTag parse(byte[] raw) throws CorruptObjectException {
/**
* Parse an annotated tag from its canonical format.
*
* <p>
* This method inserts the tag directly into the caller supplied revision
* pool, making it appear as though the tag exists in the repository, even
* if it doesn't. The repository under the pool is not affected.
* <p>
* The body of the tag (message, tagger, signature) is always retained in
* the returned {@code RevTag}, even if the supplied {@code RevWalk} has
* been configured with {@code setRetainBody(false)}.
*
* @param rw
* the revision pool to allocate the tag within. The tag's object
* pointer will be obtained from this pool.
* @param raw
* the canonical formatted tag to be parsed.
* the canonical formatted tag to be parsed. This buffer will be
* retained by the returned {@code RevTag} and must not be
* modified by the caller.
* @return the parsed tag, in an isolated revision pool that is not
* available to the caller.
* @throws CorruptObjectException
@ -104,13 +110,12 @@ public static RevTag parse(byte[] raw) throws CorruptObjectException {
*/
public static RevTag parse(RevWalk rw, byte[] raw)
throws CorruptObjectException {
ObjectInserter.Formatter fmt = new ObjectInserter.Formatter();
boolean retain = rw.isRetainBody();
rw.setRetainBody(true);
RevTag r = rw.lookupTag(fmt.idFor(Constants.OBJ_TAG, raw));
r.parseCanonical(rw, raw);
rw.setRetainBody(retain);
return r;
try (ObjectInserter.Formatter fmt = new ObjectInserter.Formatter()) {
RevTag r = rw.lookupTag(fmt.idFor(Constants.OBJ_TAG, raw));
r.parseCanonical(rw, raw);
r.buffer = raw;
return r;
}
}
private RevObject object;
@ -265,7 +270,18 @@ public final String getTagName() {
return tagName;
}
final void disposeBody() {
/**
* Discard the message buffer to reduce memory usage.
* <p>
* After discarding the memory usage of the {@code RevTag} is reduced to
* only the {@link #getObject()} pointer and {@link #getTagName()}.
* Accessing other properties such as {@link #getTaggerIdent()} or either
* message function requires reloading the buffer by invoking
* {@link RevWalk#parseBody(RevObject)}.
*
* @since 4.0
*/
public final void disposeBody() {
buffer = null;
}
}

View File

@ -192,7 +192,7 @@ public class RevWalk implements Iterable<RevCommit>, AutoCloseable {
private TreeFilter treeFilter;
private boolean retainBody;
private boolean retainBody = true;
private boolean rewriteParents = true;
@ -233,7 +233,6 @@ private RevWalk(ObjectReader or, boolean closeReader) {
sorting = EnumSet.of(RevSort.NONE);
filter = RevFilter.ALL;
treeFilter = TreeFilter.ALL;
retainBody = true;
this.closeReader = closeReader;
}
@ -607,6 +606,9 @@ boolean getRewriteParents() {
* Usually the body is always retained, but some application code might not
* care and would prefer to discard the body of a commit as early as
* possible, to reduce memory usage.
* <p>
* True by default on {@link RevWalk} and false by default for
* {@link ObjectWalk}.
*
* @return true if the body should be retained; false it is discarded.
*/
@ -620,6 +622,9 @@ public boolean isRetainBody() {
* If a body of a commit or tag is not retained, the application must
* call {@link #parseBody(RevObject)} before the body can be safely
* accessed through the type specific access methods.
* <p>
* True by default on {@link RevWalk} and false by default for
* {@link ObjectWalk}.
*
* @param retain true to retain bodies; false to discard them early.
*/

View File

@ -85,8 +85,6 @@ RevCommit next() throws MissingObjectException,
final TreeFilter tf = w.getTreeFilter();
AbstractRevQueue q = walker.queue;
w.reader.walkAdviceBeginCommits(w, w.roots);
if (rf == RevFilter.MERGE_BASE) {
// Computing for merge bases is a special case and does not
// use the bulk of the generator pipeline.
@ -144,7 +142,7 @@ RevCommit next() throws MissingObjectException,
} else {
g = new PendingGenerator(w, pending, rf, pendingOutputType);
if (boundary) {
if (walker.hasRevSort(RevSort.BOUNDARY)) {
// Because the boundary generator may produce uninteresting
// commits we cannot allow the pending generator to dispose
// of them early.

View File

@ -0,0 +1,93 @@
/**
* Copyright (C) 2015, 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.revwalk.filter;
import java.io.IOException;
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.revwalk.ObjectWalk;
/**
* Selects interesting objects when walking.
* <p>
* Applications should install the filter on an ObjectWalk by
* {@link ObjectWalk#setObjectFilter(ObjectFilter)} prior to starting traversal.
*
* @since 4.0
*/
public abstract class ObjectFilter {
/** Default filter that always returns true. */
public static final ObjectFilter ALL = new AllFilter();
private static final class AllFilter extends ObjectFilter {
@Override
public boolean include(ObjectWalk walker, AnyObjectId o) {
return true;
}
}
/**
* Determine if the named object should be included in the walk.
*
* @param walker
* the active walker this filter is being invoked from within.
* @param objid
* the object currently being tested.
* @return {@code true} if the named object should be included in the walk.
* @throws MissingObjectException
* an object the filter needed to consult to determine its
* answer was missing
* @throws IncorrectObjectTypeException
* an object the filter needed to consult to determine its
* answer was of the wrong type
* @throws IOException
* an object the filter needed to consult to determine its
* answer could not be read.
*/
public abstract boolean include(ObjectWalk walker, AnyObjectId objid)
throws MissingObjectException, IncorrectObjectTypeException,
IOException;
}

View File

@ -489,16 +489,14 @@ private void putImpl(final String bucket, final String key,
final String md5str = Base64.encodeBytes(csum);
final long len = buf.length();
final String lenstr = String.valueOf(len);
for (int curAttempt = 0; curAttempt < maxAttempts; curAttempt++) {
final HttpURLConnection c = open("PUT", bucket, key); //$NON-NLS-1$
c.setRequestProperty("Content-Length", lenstr); //$NON-NLS-1$
c.setFixedLengthStreamingMode(len);
c.setRequestProperty("Content-MD5", md5str); //$NON-NLS-1$
c.setRequestProperty(X_AMZ_ACL, acl);
encryption.request(c, X_AMZ_META);
authorize(c);
c.setDoOutput(true);
c.setFixedLengthStreamingMode((int) len);
monitor.beginTask(monitorTask, (int) (len / 1024));
final OutputStream os = c.getOutputStream();
try {

View File

@ -1143,7 +1143,6 @@ private void checkConnectivity() throws IOException {
parser = null;
try (final ObjectWalk ow = new ObjectWalk(db)) {
ow.setRetainBody(false);
if (baseObjects != null) {
ow.sort(RevSort.TOPO);
if (!baseObjects.isEmpty())
@ -1461,9 +1460,11 @@ protected void sendStatusReport(final boolean forClient,
case REJECTED_MISSING_OBJECT:
if (cmd.getMessage() == null)
r.append("missing object(s)"); //$NON-NLS-1$
else if (cmd.getMessage().length() == Constants.OBJECT_ID_STRING_LENGTH)
r.append("object " + cmd.getMessage() + " missing"); //$NON-NLS-1$ //$NON-NLS-2$
else
else if (cmd.getMessage().length() == Constants.OBJECT_ID_STRING_LENGTH) {
r.append("object "); //$NON-NLS-1$
r.append(cmd.getMessage());
r.append(" missing"); //$NON-NLS-1$
} else
r.append(cmd.getMessage());
break;

View File

@ -199,7 +199,7 @@ public boolean include(TreeWalk tw) throws MissingObjectException,
// If i is cnt then the path does not appear in any other tree,
// and this working tree entry can be safely ignored.
return i == cnt ? false : true;
return i != cnt;
} else {
// In working tree and not ignored, and not in DirCache.
return true;

View File

@ -66,140 +66,70 @@
* @since 3.0
*/
public class FS_POSIX extends FS {
private static final int DEFAULT_UMASK = 0022;
private volatile int umask = -1;
static {
String umask = readUmask();
// umask return value consists of 3 or 4 digits, like "002" or "0002"
if (umask != null && umask.length() > 0 && umask.matches("\\d{3,4}")) { //$NON-NLS-1$
EXECUTE_FOR_OTHERS = isGranted(PosixFilePermission.OTHERS_EXECUTE,
umask);
EXECUTE_FOR_GROUP = isGranted(PosixFilePermission.GROUP_EXECUTE,
umask);
} else {
EXECUTE_FOR_OTHERS = null;
EXECUTE_FOR_GROUP = null;
}
/** Default constructor. */
protected FS_POSIX() {
}
/**
* @since 4.0
* Constructor
*
* @param src
* FS to copy some settings from
*/
protected static final Boolean EXECUTE_FOR_OTHERS;
/**
* @since 4.0
*/
protected static final Boolean EXECUTE_FOR_GROUP;
protected FS_POSIX(FS src) {
super(src);
if (src instanceof FS_POSIX) {
umask = ((FS_POSIX) src).umask;
}
}
@Override
public FS newInstance() {
return new FS_POSIX();
return new FS_POSIX(this);
}
/**
* Derives requested permission from given octal umask value as defined e.g.
* in <a href="http://linux.die.net/man/2/umask">http://linux.die.net/man/2/
* umask</a>.
* <p>
* The umask expected here must consist of 3 or 4 digits. Last three digits
* are significant here because they represent file permissions granted to
* the "owner", "group" and "others" (in this order).
* <p>
* Each single digit from the umask represents 3 bits of the mask standing
* for "<b>r</b>ead, <b>w</b>rite, e<b>x</b>ecute" permissions (in this
* order).
* <p>
* The possible umask values table:
* Set the umask, overriding any value observed from the shell.
*
* <pre>
* Value : Bits:Abbr.: Permission
* 0 : 000 :rwx : read, write and execute
* 1 : 001 :rw : read and write
* 2 : 010 :rx : read and execute
* 3 : 011 :r : read only
* 4 : 100 :wx : write and execute
* 5 : 101 :w : write only
* 6 : 110 :x : execute only
* 7 : 111 : : no permissions
* </pre>
* <p>
* Note, that umask value is used to "mask" the requested permissions on
* file creation by combining the requested permission bit with the
* <b>negated</b> value of the umask bit.
* <p>
* Simply speaking, if a bit is <b>not</b> set in the umask, then the
* appropriate right <b>will</b> be granted <b>if</b> requested. If a bit is
* set in the umask value, then the appropriate permission will be not
* granted.
* <p>
* Example:
* <li>umask 023 ("000 010 011" or rwx rx r) combined with the request to
* create an executable file with full set of permissions for everyone (777)
* results in the file with permissions 754 (rwx rx r).
* <li>umask 002 ("000 000 010" or rwx rwx rx) combined with the request to
* create an executable file with full set of permissions for everyone (777)
* results in the file with permissions 775 (rwx rwx rx).
* <li>umask 002 ("000 000 010" or rwx rwx rx) combined with the request to
* create a file without executable rights for everyone (666) results in the
* file with permissions 664 (rw rw r).
*
* @param p
* non null permission
* @param umask
* octal umask value represented by at least three digits. The
* digits (read from the end to beginning of the umask) represent
* permissions for "others", "group" and "owner".
*
* @return true if the requested permission is set according to given umask
* mask to apply when creating files.
* @since 4.0
*/
protected static Boolean isGranted(PosixFilePermission p, String umask) {
char val;
switch (p) {
case OTHERS_EXECUTE:
// Read last digit, because umask is ordered as: User/Group/Others.
val = umask.charAt(umask.length() - 1);
return isExecuteGranted(val);
case GROUP_EXECUTE:
val = umask.charAt(umask.length() - 2);
return isExecuteGranted(val);
default:
throw new UnsupportedOperationException(
"isGranted() for " + p + " is not implemented!"); //$NON-NLS-1$ //$NON-NLS-2$
public void setUmask(int umask) {
this.umask = umask;
}
private int umask() {
int u = umask;
if (u == -1) {
u = readUmask();
umask = u;
}
return u;
}
/**
* @param c
* character representing octal permission value from the table
* in {@link #isGranted(PosixFilePermission, String)}
* @return true if the "execute" permission is granted according to given
* character
*/
private static Boolean isExecuteGranted(char c) {
if (c == '0' || c == '2' || c == '4' || c == '6')
return Boolean.TRUE;
return Boolean.FALSE;
}
/**
* @return umask returned from running umask command in a shell
* @since 4.0
*/
protected static String readUmask() {
Process p;
/** @return mask returned from running {@code umask} command in shell. */
private static int readUmask() {
try {
p = Runtime.getRuntime().exec(
new String[] { "sh", "-c", "umask" }, null, null); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
Process p = Runtime.getRuntime().exec(
new String[] { "sh", "-c", "umask" }, //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
null, null);
try (BufferedReader lineRead = new BufferedReader(
new InputStreamReader(p.getInputStream(), Charset
.defaultCharset().name()))) {
p.waitFor();
return lineRead.readLine();
if (p.waitFor() == 0) {
String s = lineRead.readLine();
if (s.matches("0?\\d{3}")) { //$NON-NLS-1$
return Integer.parseInt(s, 8);
}
}
return DEFAULT_UMASK;
}
} catch (Exception e) {
return null;
return DEFAULT_UMASK;
}
}
@ -229,23 +159,6 @@ protected File discoverGitPrefix() {
return null;
}
/**
* Default constructor
*/
protected FS_POSIX() {
super();
}
/**
* Constructor
*
* @param src
* FS to copy some settings from
*/
protected FS_POSIX(FS src) {
super(src);
}
@Override
public boolean isCaseSensitive() {
return !SystemReader.getInstance().isMacOS();
@ -265,35 +178,40 @@ public boolean canExecute(File f) {
public boolean setExecute(File f, boolean canExecute) {
if (!isFile(f))
return false;
// only if the execute has to be set, and we know the umask
if (canExecute && EXECUTE_FOR_OTHERS != null) {
try {
Path path = f.toPath();
Set<PosixFilePermission> pset = Files
.getPosixFilePermissions(path);
// user is always allowed to set execute
pset.add(PosixFilePermission.OWNER_EXECUTE);
if (!canExecute)
return f.setExecutable(false);
if (EXECUTE_FOR_GROUP.booleanValue())
pset.add(PosixFilePermission.GROUP_EXECUTE);
try {
Path path = f.toPath();
Set<PosixFilePermission> pset = Files.getPosixFilePermissions(path);
if (EXECUTE_FOR_OTHERS.booleanValue())
pset.add(PosixFilePermission.OTHERS_EXECUTE);
// owner (user) is always allowed to execute.
pset.add(PosixFilePermission.OWNER_EXECUTE);
Files.setPosixFilePermissions(path, pset);
return true;
} catch (IOException e) {
// The interface doesn't allow to throw IOException
final boolean debug = Boolean.parseBoolean(SystemReader
.getInstance().getProperty("jgit.fs.debug")); //$NON-NLS-1$
if (debug)
System.err.println(e);
return false;
}
int mask = umask();
apply(pset, mask, PosixFilePermission.GROUP_EXECUTE, 1 << 3);
apply(pset, mask, PosixFilePermission.OTHERS_EXECUTE, 1);
Files.setPosixFilePermissions(path, pset);
return true;
} catch (IOException e) {
// The interface doesn't allow to throw IOException
final boolean debug = Boolean.parseBoolean(SystemReader
.getInstance().getProperty("jgit.fs.debug")); //$NON-NLS-1$
if (debug)
System.err.println(e);
return false;
}
}
private static void apply(Set<PosixFilePermission> set,
int umask, PosixFilePermission perm, int test) {
if ((umask & test) == 0) {
// If bit is clear in umask, permission is allowed.
set.add(perm);
} else {
// If bit is set in umask, permission is denied.
set.remove(perm);
}
// if umask is not working for some reason: fall back to default (buggy)
// implementation which does not consider umask: see bug 424395
return f.setExecutable(canExecute);
}
@Override

View File

@ -111,18 +111,20 @@ protected File discoverGitPrefix() {
if (gitExe != null)
return resolveGrandparentFile(gitExe);
// This isn't likely to work, if bash is in $PATH, git should
// also be in $PATH. But its worth trying.
//
String w = readPipe(userHome(), //
new String[] { "bash", "--login", "-c", "which git" }, // //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
Charset.defaultCharset().name());
if (w != null) {
// The path may be in cygwin/msys notation so resolve it right away
gitExe = resolve(null, w);
if (gitExe != null)
return resolveGrandparentFile(gitExe);
if (searchPath(path, "bash.exe") != null) { //$NON-NLS-1$
// This isn't likely to work, but its worth trying:
// If bash is in $PATH, git should also be in $PATH.
String w = readPipe(userHome(),
new String[] { "bash", "--login", "-c", "which git" }, // //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
Charset.defaultCharset().name());
if (w != null) {
// The path may be in cygwin/msys notation so resolve it right away
gitExe = resolve(null, w);
if (gitExe != null)
return resolveGrandparentFile(gitExe);
}
}
return null;
}

View File

@ -185,7 +185,7 @@
<commons-compress-version>1.6</commons-compress-version>
<osgi-core-version>4.3.1</osgi-core-version>
<servlet-api-version>2.5</servlet-api-version>
<jetty-version>7.6.14.v20131031</jetty-version>
<jetty-version>9.2.10.v20150310</jetty-version>
<clirr-version>2.6.1</clirr-version>
<httpclient-version>4.1.3</httpclient-version>
<slf4j-version>1.7.2</slf4j-version>