diff --git a/plugins/scm-git-plugin/pom.xml b/plugins/scm-git-plugin/pom.xml
index 03059db1bd..1f90d6868c 100644
--- a/plugins/scm-git-plugin/pom.xml
+++ b/plugins/scm-git-plugin/pom.xml
@@ -17,6 +17,12 @@
+
+ sonia.scm
+ scm-web-api
+ 1.0-SNAPSHOT
+
+
javax.servlet
servlet-api
@@ -25,11 +31,28 @@
- sonia.scm
- scm-web-api
- 1.0-SNAPSHOT
+ org.eclipse.jgit
+ org.eclipse.jgit
+ ${jgit.version}
+
+
+
+ org.eclipse.jgit
+ org.eclipse.jgit.http.server
+ ${jgit.version}
+
+ 0.9.3
+
+
+
+
+ jgit-repository
+ http://download.eclipse.org/jgit/maven
+
+
+
diff --git a/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitConfig.java b/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitConfig.java
index 4563679d1a..9f508effe6 100644
--- a/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitConfig.java
+++ b/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitConfig.java
@@ -29,6 +29,8 @@
*
*/
+
+
package sonia.scm.repository;
//~--- JDK imports ------------------------------------------------------------
@@ -40,60 +42,4 @@ import javax.xml.bind.annotation.XmlRootElement;
* @author Sebastian Sdorra
*/
@XmlRootElement(name = "config")
-public class GitConfig extends SimpleRepositoryConfig
-{
-
- /**
- * Method description
- *
- *
- * @return
- */
- public String getGitBinary()
- {
- return gitBinary;
- }
-
- /**
- * Method description
- *
- *
- * @return
- */
- public String getGitHttpBackend()
- {
- return gitHttpBackend;
- }
-
- //~--- set methods ----------------------------------------------------------
-
- /**
- * Method description
- *
- *
- * @param gitBinary
- */
- public void setGitBinary(String gitBinary)
- {
- this.gitBinary = gitBinary;
- }
-
- /**
- * Method description
- *
- *
- * @param gitHttpBackend
- */
- public void setGitHttpBackend(String gitHttpBackend)
- {
- this.gitHttpBackend = gitHttpBackend;
- }
-
- //~--- fields ---------------------------------------------------------------
-
- /** Field description */
- private String gitBinary = "git";
-
- /** Field description */
- private String gitHttpBackend = "git-http-backend";
-}
+public class GitConfig extends SimpleRepositoryConfig {}
diff --git a/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryHandler.java b/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryHandler.java
index fb3a4008c3..91e149ffe5 100644
--- a/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryHandler.java
+++ b/plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitRepositoryHandler.java
@@ -37,9 +37,9 @@ package sonia.scm.repository;
import com.google.inject.Singleton;
+import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
+
import sonia.scm.Type;
-import sonia.scm.io.CommandResult;
-import sonia.scm.io.ExtendedCommand;
//~--- JDK imports ------------------------------------------------------------
@@ -80,23 +80,6 @@ public class GitRepositoryHandler
//~--- methods --------------------------------------------------------------
- /**
- * Method description
- *
- *
- * @param repository
- * @param directory
- *
- * @return
- */
- @Override
- protected ExtendedCommand buildCreateCommand(Repository repository,
- File directory)
- {
- return new ExtendedCommand(config.getGitBinary(), "init", "--bare",
- directory.getPath());
- }
-
/**
* Method description
*
@@ -108,18 +91,11 @@ public class GitRepositoryHandler
* @throws RepositoryException
*/
@Override
- protected void postCreate(Repository repository, File directory)
- throws IOException, RepositoryException
+ protected void create(Repository repository, File directory)
+ throws RepositoryException, IOException
{
- ExtendedCommand command = new ExtendedCommand(config.getGitBinary(),
- "update-server-info");
-
- command.setWorkDirectory(directory);
- execute(command);
- command = new ExtendedCommand(config.getGitBinary(), "config", "--bool",
- "--add", "http.receivepack", "true");
- command.setWorkDirectory(directory);
- execute(command);
+ new FileRepositoryBuilder().setGitDir(
+ directory).readEnvironment().findGitDir().build().create(true);
}
//~--- get methods ----------------------------------------------------------
@@ -136,30 +112,8 @@ public class GitRepositoryHandler
return GitConfig.class;
}
- //~--- methods --------------------------------------------------------------
+ //~--- fields ---------------------------------------------------------------
- /**
- * Method description
- *
- *
- * @param command
- *
- * @throws IOException
- * @throws RepositoryException
- */
- private void execute(ExtendedCommand command)
- throws IOException, RepositoryException
- {
- CommandResult result = command.execute();
-
- if (!result.isSuccessfull())
- {
- StringBuilder msg = new StringBuilder("command exit with error ");
-
- msg.append(result.getReturnCode()).append(" and message: '");
- msg.append(result.getOutput()).append("'");
-
- throw new RepositoryException(msg.toString());
- }
- }
+ /** Field description */
+ private FileRepositoryBuilder builder = new FileRepositoryBuilder();
}
diff --git a/plugins/scm-git-plugin/src/main/java/sonia/scm/web/GitRepositoryResolver.java b/plugins/scm-git-plugin/src/main/java/sonia/scm/web/GitRepositoryResolver.java
new file mode 100644
index 0000000000..4b85cf1241
--- /dev/null
+++ b/plugins/scm-git-plugin/src/main/java/sonia/scm/web/GitRepositoryResolver.java
@@ -0,0 +1,192 @@
+/**
+ * Copyright (c) 2010, Sebastian Sdorra
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of SCM-Manager; 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 REGENTS 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.
+ *
+ * http://bitbucket.org/sdorra/scm-manager
+ *
+ */
+
+
+
+package sonia.scm.web;
+
+//~--- non-JDK imports --------------------------------------------------------
+
+import org.eclipse.jgit.errors.RepositoryNotFoundException;
+import org.eclipse.jgit.http.server.resolver.RepositoryResolver;
+import org.eclipse.jgit.http.server.resolver.ServiceNotAuthorizedException;
+import org.eclipse.jgit.http.server.resolver.ServiceNotEnabledException;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.lib.RepositoryCache;
+import org.eclipse.jgit.lib.RepositoryCache.FileKey;
+import org.eclipse.jgit.util.FS;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import sonia.scm.repository.GitConfig;
+
+//~--- JDK imports ------------------------------------------------------------
+
+import java.io.File;
+import java.io.IOException;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ *
+ * @author Sebastian Sdorra
+ */
+public class GitRepositoryResolver implements RepositoryResolver
+{
+
+ /** the logger for GitRepositoryResolver */
+ private static final Logger logger =
+ LoggerFactory.getLogger(GitRepositoryResolver.class);
+
+ //~--- constructors ---------------------------------------------------------
+
+ /**
+ * Constructs ...
+ *
+ *
+ * @param config
+ */
+ public GitRepositoryResolver(GitConfig config)
+ {
+ this.config = config;
+ }
+
+ //~--- get methods ----------------------------------------------------------
+
+ /**
+ * Method description
+ *
+ *
+ * @param name
+ *
+ * @return
+ */
+ private static boolean isUnreasonableName(final String name)
+ {
+ if (name.length() == 0)
+ {
+ return true; // no empty paths
+ }
+
+ if (name.indexOf('\\') >= 0)
+ {
+ return true; // no windows/dos style paths
+ }
+
+ if (new File(name).isAbsolute())
+ {
+ return true; // no absolute paths
+ }
+
+ if (name.startsWith("../"))
+ {
+ return true; // no "l../etc/passwd"
+ }
+
+ if (name.contains("/../"))
+ {
+ return true; // no "foo/../etc/passwd"
+ }
+
+ if (name.contains("/./"))
+ {
+ return true; // "foo/./foo" is insane to ask
+ }
+
+ if (name.contains("//"))
+ {
+ return true; // double slashes is sloppy, don't use it
+ }
+
+ return false; // is a reasonable name
+ }
+
+ //~--- methods --------------------------------------------------------------
+
+ /**
+ * Method description
+ *
+ *
+ * @param request
+ * @param repositoryName
+ *
+ * @return
+ *
+ * @throws RepositoryNotFoundException
+ * @throws ServiceNotAuthorizedException
+ * @throws ServiceNotEnabledException
+ */
+ @Override
+ public Repository open(HttpServletRequest request, String repositoryName)
+ throws RepositoryNotFoundException, ServiceNotAuthorizedException,
+ ServiceNotEnabledException
+ {
+ Repository repository = null;
+
+ if (isUnreasonableName(repositoryName))
+ {
+ throw new RepositoryNotFoundException(repositoryName);
+ }
+
+ try
+ {
+ File gitdir = new File(config.getRepositoryDirectory(), repositoryName);
+
+ if (!gitdir.exists())
+ {
+ throw new RepositoryNotFoundException(repositoryName);
+ }
+
+ repository = RepositoryCache.open(FileKey.lenient(gitdir, FS.DETECTED),
+ true);
+ }
+ catch (RuntimeException e)
+ {
+ repository.close();
+
+ throw new RepositoryNotFoundException(repositoryName, e);
+ }
+ catch (IOException e)
+ {
+ repository.close();
+
+ throw new RepositoryNotFoundException(repositoryName, e);
+ }
+
+ return repository;
+ }
+
+ //~--- fields ---------------------------------------------------------------
+
+ /** Field description */
+ private GitConfig config;
+}
diff --git a/plugins/scm-git-plugin/src/main/java/sonia/scm/web/GitWebPlugin.java b/plugins/scm-git-plugin/src/main/java/sonia/scm/web/GitWebPlugin.java
index 464e63474e..e568f24d31 100644
--- a/plugins/scm-git-plugin/src/main/java/sonia/scm/web/GitWebPlugin.java
+++ b/plugins/scm-git-plugin/src/main/java/sonia/scm/web/GitWebPlugin.java
@@ -81,7 +81,7 @@ public class GitWebPlugin implements ScmWebPlugin
protected void configureServlets()
{
filter("/git/*").through(BasicAuthenticationFilter.class);
- serve("/git/*").with(GitCGIServlet.class);
+ serve("/git/*").with(ScmGitServlet.class);
}
});
}
diff --git a/plugins/scm-git-plugin/src/main/java/sonia/scm/web/GitCGIServlet.java b/plugins/scm-git-plugin/src/main/java/sonia/scm/web/ScmGitServlet.java
similarity index 66%
rename from plugins/scm-git-plugin/src/main/java/sonia/scm/web/GitCGIServlet.java
rename to plugins/scm-git-plugin/src/main/java/sonia/scm/web/ScmGitServlet.java
index 142dd3e8b4..bee82bf7fe 100644
--- a/plugins/scm-git-plugin/src/main/java/sonia/scm/web/GitCGIServlet.java
+++ b/plugins/scm-git-plugin/src/main/java/sonia/scm/web/ScmGitServlet.java
@@ -29,6 +29,8 @@
*
*/
+
+
package sonia.scm.web;
//~--- non-JDK imports --------------------------------------------------------
@@ -36,15 +38,13 @@ package sonia.scm.web;
import com.google.inject.Inject;
import com.google.inject.Singleton;
-import sonia.scm.repository.GitConfig;
+import org.eclipse.jgit.http.server.GitServlet;
+
import sonia.scm.repository.GitRepositoryHandler;
import sonia.scm.util.IOUtil;
-import sonia.scm.web.cgi.AbstractCGIServlet;
-import sonia.scm.web.cgi.EnvList;
//~--- JDK imports ------------------------------------------------------------
-import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@@ -58,15 +58,9 @@ import javax.servlet.http.HttpServletResponse;
* @author Sebastian Sdorra
*/
@Singleton
-public class GitCGIServlet extends AbstractCGIServlet
+public class ScmGitServlet extends GitServlet
{
- /** Field description */
- public static final String ENV_HTTP_EXPORT_ALL = "GIT_HTTP_EXPORT_ALL";
-
- /** Field description */
- public static final String ENV_PROJECT_ROOT = "GIT_PROJECT_ROOT";
-
/** Field description */
public static final String MIMETYPE_HTML = "text/html";
@@ -78,56 +72,24 @@ public class GitCGIServlet extends AbstractCGIServlet
public static final String RESOURCE_GITINDEX = "/sonia/scm/git.index.html";
/** Field description */
- private static final long serialVersionUID = 9147517765161830847L;
+ private static final long serialVersionUID = -7712897339207470674L;
+
+ //~--- constructors ---------------------------------------------------------
+
+ /**
+ * Constructs ...
+ *
+ *
+ * @param handler
+ */
+ @Inject
+ public ScmGitServlet(GitRepositoryHandler handler)
+ {
+ setRepositoryResolver(new GitRepositoryResolver(handler.getConfig()));
+ }
//~--- methods --------------------------------------------------------------
- /**
- * Method description
- *
- *
- * @return
- *
- * @throws ServletException
- */
- @Override
- protected EnvList createBaseEnvironment() throws ServletException
- {
- EnvList list = super.createBaseEnvironment();
-
- list.set(ENV_HTTP_EXPORT_ALL, "");
-
- return list;
- }
-
- /**
- * Method description
- *
- *
- * @param baseEnvironment
- *
- * @return
- *
- * @throws ServletException
- */
- @Override
- protected EnvList createRequestEnvironment(EnvList baseEnvironment)
- throws ServletException
- {
- GitConfig config = repositoryHandler.getConfig();
-
- if (config == null)
- {
- throw new ServletException("git is not configured");
- }
-
- EnvList env = new EnvList(baseEnvironment);
-
- env.set(ENV_PROJECT_ROOT, config.getRepositoryDirectory().getPath());
-
- return env;
- }
-
/**
* Method description
*
@@ -155,35 +117,6 @@ public class GitCGIServlet extends AbstractCGIServlet
}
}
- //~--- get methods ----------------------------------------------------------
-
- /**
- * Method description
- *
- *
- * @param request
- *
- * @return
- *
- * @throws IOException
- * @throws ServletException
- */
- @Override
- protected File getCommand(HttpServletRequest request)
- throws ServletException, IOException
- {
- GitConfig config = repositoryHandler.getConfig();
-
- if (config == null)
- {
- throw new ServletException("git is not configured");
- }
-
- return new File(config.getGitHttpBackend());
- }
-
- //~--- methods --------------------------------------------------------------
-
/**
* Method description
*
@@ -203,7 +136,7 @@ public class GitCGIServlet extends AbstractCGIServlet
try
{
- input = GitCGIServlet.class.getResourceAsStream(RESOURCE_GITINDEX);
+ input = ScmGitServlet.class.getResourceAsStream(RESOURCE_GITINDEX);
output = response.getOutputStream();
IOUtil.copy(input, output);
}
@@ -228,10 +161,4 @@ public class GitCGIServlet extends AbstractCGIServlet
{
return request.getRequestURI().substring(request.getContextPath().length());
}
-
- //~--- fields ---------------------------------------------------------------
-
- /** Field description */
- @Inject
- private GitRepositoryHandler repositoryHandler;
}
diff --git a/plugins/scm-git-plugin/src/main/resources/sonia/scm/git.config.js b/plugins/scm-git-plugin/src/main/resources/sonia/scm/git.config.js
index 9cba6f4b7e..a452710302 100644
--- a/plugins/scm-git-plugin/src/main/resources/sonia/scm/git.config.js
+++ b/plugins/scm-git-plugin/src/main/resources/sonia/scm/git.config.js
@@ -33,11 +33,6 @@ registerConfigPanel({
xtype : 'configForm',
title : 'Git Settings',
items : [{
- xtype : 'textfield',
- fieldLabel : 'Git Binary',
- name : 'gitBinary',
- allowBlank : false
- },{
xtype: 'textfield',
name: 'repositoryDirectory',
fieldLabel: 'Repository directory',
@@ -47,11 +42,6 @@ registerConfigPanel({
name: 'baseUrl',
fieldLabel: 'Base URL',
allowBlank : false
- },{
- xtype : 'textfield',
- fieldLabel : 'Git-Http-Backend',
- name : 'gitHttpBackend',
- allowBlank : false
}],
onSubmit: function(values){