8

途中でクローン操作を強制終了する方法はありますか?クローンを使用してリポジトリを検証しますか?リモートURL/リポジトリが有効かどうかをテストする他の方法はありますか?

4

7 に答える 7

5

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());
    }
于 2016-03-04T09:58:22.547 に答える
4

次のヒューリスティックを使用しています(さらに改善する必要があります):

private final static String INFO_REFS_PATH = "info/refs";

public static boolean isValidRepository(URIish repoUri) {
  if (repoUri.isRemote()) {
    return isValidRemoteRepository(repoUri);
  } else {
    return isValidLocalRepository(repoUri);
  }
}

private static boolean isValidLocalRepository(URIish repoUri) {
  boolean result;
  try {
    result = new FileRepository(repoUri.getPath()).getObjectDatabase().exists();
  } catch (IOException e) {
    result = false;
  }
  return result;
}

private static boolean isValidRemoteRepository(URIish repoUri) {
  boolean result;

  if (repoUri.getScheme().toLowerCase().startsWith("http") ) {
    String path = repoUri.getPath();
    String newPath = path.endsWith("/")? path + INFO_REFS_PATH : path + "/" + INFO_REFS_PATH;
    URIish checkUri = repoUri.setPath(newPath);

    InputStream ins = null;
    try {
      URLConnection conn = new URL(checkUri.toString()).openConnection();
      conn.setReadTimeout(NETWORK_TIMEOUT_MSEC);
      ins = conn.getInputStream();
      result = true;
    } catch (Exception e) {
      result = false;
    } finally {
      try { ins.close(); } catch (Exception e) { /* ignore */ }
    }

  } else if (repoUri.getScheme().toLowerCase().startsWith("ssh") ) {

    RemoteSession ssh = null;
    Process exec = null;

    try {
      ssh = SshSessionFactory.getInstance().getSession(repoUri, null, FS.detect(), 5000);
      exec = ssh.exec("cd " + repoUri.getPath() +"; git rev-parse --git-dir", 5000);

      Integer exitValue = null;
      do {
        try {
          exitValue = exec.exitValue();
        } catch (Exception e) { 
          try{Thread.sleep(1000);}catch(Exception ee){}
        }
      } while (exitValue == null);

      result = exitValue == 0;

    } catch (Exception e) {
      result = false;

    } finally {
      try { exec.destroy(); } catch (Exception e) { /* ignore */ }
      try { ssh.disconnect(); } catch (Exception e) { /* ignore */ }
    }

  } else {
    // TODO need to implement tests for other schemas
    result = true;
  }
  return result;
}

これは、裸および非裸のリポジトリでうまく機能します。

URIish.isRemote() メソッドに問題があるようです。ファイル URL から URIish を作成すると、ホストは null ではなく空の文字列になります! ただし、ホスト フィールドが null でない場合、URIish.isRemote() は true を返します...

編集: isValidRemoteRepository() メソッドに ssh サポートを追加しました。

于 2012-10-04T14:17:29.143 に答える
1

JGit のソースを調べたところ、リモート リポジトリの有効性を確認する方法がないようです。

これは次のcall方法です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 が無効かどうかを取得するために、 a をキャッチすると、またはを検索しJGitInternalException eて実際の原因を取得できますが、指摘したように、実際に有効な場合はクローンを作成します。ライブラリでは、操作を中断することはできません。e.getCause()InvalidRemoteExceptionURISyntaxException

JGit コードをさらに深く掘り下げると、TransportLocalクラスにはがスローopen(URIsh,Repository,String)されたかどうかを確認するために使用できるメソッドがありますがInvalidRemoteException、そのコンストラクターはパブリックではありません。残念ながら、日曜大工のソリューションが必要です。TransportLocal.open私が言及した方法の内容から始めることができるかもしれません。

于 2012-06-14T10:46:04.463 に答える
0

AFAIK JGitにはgit fsckまだ実装がありません。

于 2012-08-23T20:51:24.417 に答える
0

見ている人には、次のより一般的なアプローチを使用して、リモート リポジトリを検証しています (コードは C# ですが、Java に変換するのは難しくありません)。

public static bool IsValidRemoteRepository(URIish repoUri, CredentialsProvider credentialsProvider = null)
{
    var repoPath = Path.Combine(Path.GetTempPath(), Path.GetFileNameWithoutExtension(Path.GetRandomFileName()));

    Directory.CreateDirectory(repoPath);

    var git = Git.Init().SetBare(true).SetDirectory(repoPath).Call();

    var config = git.GetRepository().GetConfig();
    config.SetString("remote", "origin", "url", repoUri.ToString());
    config.Save();

    try
    {
        var cmd = git.LsRemote();

        if (credentialsProvider != null)
        {
            cmd.SetCredentialsProvider(credentialsProvider);
        }

        cmd.SetRemote("origin").Call();
    }
    catch (TransportException e)
    {
        LastException = e;
        return false;
    }

    return true;
}
于 2012-12-19T16:39:38.193 に答える