使用JGit库搭建自定义Git服务器 (一) 搭建一个Demo工程

/ Java / 没有评论 / 2316浏览

使用JGit库搭建自定义Git服务器 (一) 搭建一个Demo工程

如果只是自己搭建个Git私服用来保存自己的代码的话不适合本项目, 本项目是用Java自定义一个Git服务器, 类似GitHub, Gitee等。这个Git服务器是用来接受来自Git客户端的git clone, git push 等命令 ,创建一个Java web工程, 最好使用maven, 如果忘记添加模块, 可以右键项目 - Add Frameworks Support。 1

1. 先是pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.gityou.server</groupId>
    <artifactId>git-server</artifactId>
    <version>1.0-SNAPSHOT</version>
     
    <packaging>war</packaging>
     
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <dependencies>
        <!-- servlet-api -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
        </dependency>
        <!-- jGit -->
        <dependency>
            <groupId>org.eclipse.jgit</groupId>
            <artifactId>org.eclipse.jgit.http.server</artifactId>
            <version>5.5.0.201909110433-r</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <version>1.6.6</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>3.2.0</version>
            </plugin>
        </plugins>
    </build>

</project>

slf4j其实jgit.servlet里就有了, 注意这里添加的是slf4j-simple, 目的是自动配置好默认的log4j配置。

maven-war-plugins也是默认就有的, 这里再次添加是为了使用高版本的(3.2.0), 据说低版本在打包是会有点小出入, 可以使用IDEA的Debug工具来运行项目, 可以打包手动放到tomcat中运行, 目前是开发阶段就先使用前者吧, 怎么配置大家应该都很熟练吧

2. 创建GitServlet.java

package com.gityou.server;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;

@WebServlet(name = "gitServer", urlPatterns = {"/*"},
        loadOnStartup = 1,
        initParams = {
                @WebInitParam(name = "base-path", value = "D:\\tmp\\gityou\\repository"),
                @WebInitParam(name = "export-all", value = "true")
        })
public class GitServlet extends org.eclipse.jgit.http.server.GitServlet {
    
}

base-path是你的服务器Repository所在位置的地址, 根据实际情况来。好了这样就可以运行了, 运行后测试一下, 是不是成功了呢, 如果没有成功, 不要急慢慢Debug, 哈哈蛤 2

就这么简单? 那肯定不行了, 如果我们的仓库位置不一样呢, 或者我们要控制某些用的访问权限, 以及监控用户等等的呢? 先来个允许自定义Repository位置的方式

Pom文件不用动, 修改GitServlet.java文件

package com.gityou.server;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;

@WebServlet(name = "gitServer", urlPatterns = {"/*"},
        loadOnStartup = 1,
        initParams = {
                @WebInitParam(name = "base-path", value = "D:\\tmp\\gityou\\repository"),
                @WebInitParam(name = "export-all", value = "true")
        })
public class GitServlet extends org.eclipse.jgit.http.server.GitServlet {
    @Override
    public void init(ServletConfig config) throws ServletException {
        // 自定义
        setRepositoryResolver(new GitHttpResolver());
        super.init(config);
    }
}

我们要重写init方法, RepositoryResolver就是用户在每次访问时用来创建new Repository的, 那我们只需要按照自己的方法写不就可以实现任意修改Repository位置了, 甚至是从数据库中读取位置都可以。

注意: set之后一定要super.init(config); 而且顺序不能变! 网上相关的例子基本上找不到, 好不容易找到了一个例子, 但是没有这一条, 整的我怎么搞都搞不定,每次都显示not found, 一气之下把jgit.server相关的源码都读了一遍, 终于得知, 在重写init()方法之后无法注册一系列的filter, 因此导致每次访问时都匹配不到filter

接下来自己实现一个创建Repository的GitHttpResolver.java文件

package com.gityou.server;

import org.eclipse.jgit.errors.RepositoryNotFoundException;
import org.eclipse.jgit.internal.storage.file.FileRepository;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.transport.ServiceMayNotContinueException;
import org.eclipse.jgit.transport.resolver.RepositoryResolver;
import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException;
import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

public class GitHttpResolver implements RepositoryResolver<HttpServletRequest> {
    @Override
    public Repository open(HttpServletRequest request, String name) throws RepositoryNotFoundException, ServiceNotAuthorizedException, ServiceNotEnabledException, ServiceMayNotContinueException {
        System.out.println("ServletPath: " + request.getServletPath());
        System.out.println("name: " + name);

        try {
            return new FileRepository("D:\\tmp\\gityou\\repository\\xiaorui\\url.git\\.git");
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}

继承RepositoryResolver这个类, 然后重写open方法就是了, Git服务器每次就是调用这个方法打开Repository。

虽然简单, 但是开启了发挥你无限想象力的大门, 哈哈哈. 注意: Git服务器中一般都是使用裸仓库, 但是为了测试方便, 我在这里没有使用; 如果不是裸仓库, 记得path要到git文件夹的位置, 也就是到.git这个文件夹 3

再次测试, 是不是成功了呢?接下来慢慢更新, 一步步完善这个项目