Java JGIT验证存储库是否有效

Java JGIT验证存储库是否有效,java,validation,jgit,Java,Validation,Jgit,是否有方法中途终止克隆操作? 我将只使用克隆来验证存储库? 是否有其他方法来测试远程url/存储库是否有效?我查看了JGit来源,似乎没有一种方法来检查远程回购的有效性 这是CloneCommand的调用方法: public Git call() throws JGitInternalException { try { URIish u = new URIish(uri); Repository repository = init(u);

是否有方法中途终止克隆操作? 我将只使用克隆来验证存储库?
是否有其他方法来测试远程url/存储库是否有效?

我查看了JGit来源,似乎没有一种方法来检查远程回购的有效性

这是
CloneCommand
调用方法:

public Git call() throws JGitInternalException {
    try {
        URIish u = new URIish(uri);
        Repository repository = init(u);
        FetchResult result = fetch(repository, u);
        if (!noCheckout)
            checkout(repository, result);
        return new Git(repository);
    } catch (IOException ioe) {
        throw new JGitInternalException(ioe.getMessage(), ioe);
    } catch (InvalidRemoteException e) {
        throw new JGitInternalException(e.getMessage(), e);
    } catch (URISyntaxException e) {
        throw new JGitInternalException(e.getMessage(), e);
    }
}
为了获取远程URL是否无效,在捕获
jgitinernalexception
e
时,您可以使用
e.getCause()
获取实际原因,以查找
InvalidRemoteException
甚至
URISyntaxException
,但正如您所指出的,如果它确实有效,您最终会进行克隆;库不允许您中断操作


深入研究JGit代码,
TransportLocal
类具有
open(URIsh、Repository、String)
方法,可以用来检查是否抛出了
InvalidRemoteException
,但其构造函数不是公共的。唉,需要一个自己动手的解决方案。您可以从我提到的
TransportLocal.open
方法的内容开始。

AFAIK JGit还没有实现
git fsck

我正在使用以下启发式方法(有待进一步改进):

这适用于裸存储库和非裸存储库

请注意,URIish.isRemote()方法似乎有问题。当您从文件URL创建URISH时,主机不是null而是空字符串!但是,如果主机字段不为null,则返回true


编辑:向isValidRemoteRepository()方法添加了ssh支持

对于任何人来说,我使用以下更通用的方法来验证远程存储库(代码是C#,但将其转换为java应该不难)


您可以使用JGIT调用“gitlsremote”。看

示例代码如下:

    final LsRemoteCommand lsCmd = new LsRemoteCommand(null);
    final List<String> repos = Arrays.asList(
            "https://github.com/MuchContact/java.git",
            "git@github.com:MuchContact/java.git");
    for (String gitRepo: repos){
        lsCmd.setRemote(gitRepo);
        System.out.println(lsCmd.call().toString());
    }
final LsRemoteCommand lsCmd=new LsRemoteCommand(null);
最终列表repos=Arrays.asList(
"https://github.com/MuchContact/java.git",
"git@github.com:MuchContact/java.git”);
for(字符串gitRepo:repos){
lsCmd.setRemote(gitRepo);
System.out.println(lsCmd.call().toString());
}

JGit正在致力于实现
git fsck
命令,但据我所知,该命令尚未发布

有关其外观的示例,请检查此项


用于验证远程存储库的API

public boolean validateRepository(String repositoryURL, String username, String password) throws Exception {
    boolean result = false;
    Repository db = FileRepositoryBuilder.create(new File("/tmp"));
    Git git = Git.wrap(db);
    final LsRemoteCommand lsCmd = git.lsRemote();
    lsCmd.setRemote(repositoryURL);
    if (username != null && password != null) {
        lsCmd.setCredentialsProvider(new UsernamePasswordCredentialsProvider(username, password));
    }
    if (null != lsCmd.call()){
        result = true;
    }
    return result;
}
注意:jgit的ls远程api抛出NPE,这是已知的错误。因此,添加了bug注释中提到的解决方法。

用于检测本地回购是否有效的代码在所有情况下都不正确,即使部分克隆的回购处于无效状态,它也将返回true。有关处理此场景的一些代码,请参见答案。这将返回
true
new-urish(新文件(“/tmp”).toURI().toURL()).isRemote()
,因此至少应该执行
repoUri.isRemote()!repoUri.getScheme().equals(“文件”)
。你能看一下吗。我想这正是您想要的。您可以使用JGIT调用“git ls remote”。请参见()只包含代码的答案永远不是答案。请详细说明,明白了。谢谢@亚视界
    final LsRemoteCommand lsCmd = new LsRemoteCommand(null);
    final List<String> repos = Arrays.asList(
            "https://github.com/MuchContact/java.git",
            "git@github.com:MuchContact/java.git");
    for (String gitRepo: repos){
        lsCmd.setRemote(gitRepo);
        System.out.println(lsCmd.call().toString());
    }
@Test
public void testHealthyRepo() throws Exception {
    RevCommit commit0 = git.commit().message("0").create();
    RevCommit commit1 = git.commit().message("1").parent(commit0).create();
    git.update("master", commit1);

    DfsFsck fsck = new DfsFsck(repo);
    FsckError errors = fsck.check(null);

    assertEquals(errors.getCorruptObjects().size(), 0);
    assertEquals(errors.getMissingObjects().size(), 0);
    assertEquals(errors.getCorruptIndices().size(), 0);
}
public boolean validateRepository(String repositoryURL, String username, String password) throws Exception {
    boolean result = false;
    Repository db = FileRepositoryBuilder.create(new File("/tmp"));
    Git git = Git.wrap(db);
    final LsRemoteCommand lsCmd = git.lsRemote();
    lsCmd.setRemote(repositoryURL);
    if (username != null && password != null) {
        lsCmd.setCredentialsProvider(new UsernamePasswordCredentialsProvider(username, password));
    }
    if (null != lsCmd.call()){
        result = true;
    }
    return result;
}