2012-06-14 25 views
6

Có phương pháp nào để giết hoạt động sao chép giữa luồng không? Tôi sẽ chỉ sử dụng nhân bản để xác thực kho lưu trữ? Có cách nào khác để kiểm tra xem url/kho lưu trữ từ xa có hợp lệ không?JGIT xác thực nếu kho lưu trữ hợp lệ

+0

Bạn có thể xem xét [câu trả lời này] (http://stackoverflow.com/a/13606879/640012) hay không. Tôi nghĩ rằng đây chính xác là những gì bạn đang tìm kiếm. – Abhishek

+0

bạn có thể gọi 'git ls-remote ' bằng cách sử dụng JGIT. xem tại (http://superuser.com/questions/227509/git-ping-check-if-remote-repository-exists) – Muco

Trả lời

1

Tôi đã xem xét các nguồn JGit và dường như không có một phương pháp để kiểm tra tính hợp lệ của repo từ xa.

Đây là phương pháp call của 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); 
    } 
} 

Để có được nếu URL từ xa là không hợp lệ, khi bắt một JGitInternalExceptione bạn có thể nhận ra nguyên nhân thực tế với e.getCause() để tìm InvalidRemoteException hoặc thậm chí URISyntaxException , nhưng khi bạn chỉ ra bạn kết thúc nhân bản nếu nó thực sự là hợp lệ; thư viện không cho phép bạn làm gián đoạn hoạt động.

Chuyển sâu hơn vào mã JGit, lớp TransportLocal có phương thức open(URIsh,Repository,String) mà bạn có thể đã sử dụng để kiểm tra xem InvalidRemoteException có bị ném hay không, nhưng hàm tạo của nó không được công khai. Một giải pháp do-it-yourself là bắt buộc, than ôi. Bạn có thể bắt đầu từ nội dung của phương pháp TransportLocal.open tôi đã đề cập.

0

AFAIK JGit chưa thực hiện git fsck.

3

Tôi đang sử dụng heuristic sau (phải được cải thiện hơn nữa):

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; 
} 

này hoạt động tốt với các kho trần và phi trần.

Xin lưu ý rằng có vẻ như đã xảy ra sự cố với phương thức URIish.isRemote(). Khi bạn tạo một URIish từ một tệp-URL, host không phải là null mà là một chuỗi rỗng! URIish.isRemote() tuy nhiên trả về true, nếu trường máy chủ không rỗng ...

EDIT: Đã thêm hỗ trợ ssh vào phương thức isValidRemoteRepository().

+1

mã được sử dụng để phát hiện xem một repo địa phương có hợp lệ hay không không đúng trong mọi trường hợp , nó sẽ trả về true ngay cả đối với một repo nhân bản vô tính trong trạng thái không hợp lệ. Xem câu trả lời [this] (http://stackoverflow.com/questions/13586502/how-to-check-if-a-git-clone-has-been-done-already-with-jgit) cho một số mã sẽ xử lý kịch bản này quá. – Adam

0

Đối với bất kỳ ai đang tìm kiếm, tôi đang sử dụng phương pháp tiếp cận chung hơn, sau đây để xác nhận một kho lưu trữ từ xa (mã trong C#, nhưng không khó để chuyển đổi nó thành 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; 
} 
2

bạn có thể gọi 'git ls-remote' bằng JGIT. nhìn thấy ở here

Mẫu mã như sau:

final LsRemoteCommand lsCmd = new LsRemoteCommand(null); 
    final List<String> repos = Arrays.asList(
      "https://github.com/MuchContact/java.git", 
      "[email protected]:MuchContact/java.git"); 
    for (String gitRepo: repos){ 
     lsCmd.setRemote(gitRepo); 
     System.out.println(lsCmd.call().toString()); 
    } 
+0

Câu trả lời chỉ bao gồm mã không bao giờ là câu trả lời. Xin hãy giải thích. – SubliemeSiem

+0

OK. Cảm ơn! @SubliemeSiem – Muco

0

JGit đang làm việc trên một thực hiện các lệnh git fsck, nhưng điều này đã không được phát hành vào ngày mvnrepository.com như xa như tôi có thể nhìn thấy.

Ví dụ về hình thức của nó, hãy kiểm tra điều này test case.

@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); 
} 
0

API để phê chuẩn kho từ xa

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; 
} 

Lưu ý: api ls-xa xôi của jgit ném NPE được biết lỗi.Vì vậy, thêm workaround như đã đề cập trong các ý kiến ​​của lỗi.
https://bugs.eclipse.org/bugs/show_bug.cgi?id=436695

Các vấn đề liên quan