有没有一种方法可以中途克服克隆操作? 我将只使用克隆来验证存储库? 是否有任何其他方式来测试远程URL /存储库是否有效?JGIT验证存储库是否有效
回答
我看了一下JGit的源代码,似乎没有提供检查远程回购有效性的方法。
这是CloneCommand
的call
方法:
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无效,捕当JGitInternalException
e
你可能会得到与e.getCause()
实际原因,寻找InvalidRemoteException
甚至URISyntaxException
,但正如你所指出的那样,如果它实际上是有效的,那么你最终会得到克隆;该库不允许您中断操作。
钻研更深入地进入JGit代码中,TransportLocal
类有你可能会用来检查一个InvalidRemoteException
抛出的open(URIsh,Repository,String)
方法,但它的构造是不公开的。一个自己动手的解决方案是必需的,唉。你可以从我提到的TransportLocal.open
方法的内容开始。
AFAIK JGit尚未实现git fsck
。我使用下面的启发式
(有待进一步提高):
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创建URI时,主机不是空的,而是空字符串! URIish.isRemote()然而返回true,如果主机字段不为空...
编辑:增加了对isValidRemoteRepository()方法的ssh支持。
用于检测本地回购有效或无效的代码在所有情况下都不正确即使对于处于无效状态的部分克隆回购,它也会返回true。看到[这](http://stackoverflow.com/questions/13586502/how-to-check-if-a-git-clone-has-been-done-already-with-jgit)回答一些代码,将处理这个场景也是。 – Adam
对于任何正在寻找的人,我使用以下更通用的方法来验证远程存储库(代码使用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;
}
您可以使用JGIT调用'git ls-remote'。看到如下here
示例代码:
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());
}
只有代码组成的答案永远不会是答案。请详细说明。 – SubliemeSiem
明白了。谢谢! @SubliemeSiem – Muco
JGit正在对git fsck
命令的执行,但是这并没有得到至于我可以看到发布mvnrepository.com。
示例如何,请检查此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);
}
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。所以添加了错误评论中提到的解决方法。
https://bugs.eclipse.org/bugs/show_bug.cgi?id=436695
- 1. 验证largeAddressAware是否有效?
- 2. JGit删除git存储库
- 3. jgit存储库浏览器
- 4. 验证裸露的Git存储库是否有数据
- 5. 存储库验证
- 6. Bean验证验证一个验证是否有效?
- 7. TYPO3 V8验证码是否有效?
- 8. 如何验证关联是否有效
- 9. 验证CSS是否有效语法
- 10. 验证Datomic实体ID是否有效
- 11. REMI存储库RPM是否经过验证或测试?
- 12. JGit:连接到远程存储库
- 13. 存储库状态在JGit中合并
- 14. 是否有JGit管道API?
- 15. 化石:“不是有效的储存库” - 删除的储存库
- 16. C是否有库存储库?
- 17. 检查存储过程是否有效
- 18. Docker:不是有效的存储库:
- 19. checkit验证是否有validate.js库中断?
- 20. 是否有任何Mongoose验证库?
- 21. 是否可以推送到没有ssl验证的nuget存储库?
- 22. 带有JGit的现有存储库的空标记列表
- 23. JGit是否支持Git凭证?
- 24. 在数据库中存储数据是否有效?
- 25. 验证是否存在
- 26. 春季CRUD存储库:是否有findOneByMaxXYZColumn()?
- 27. Localytics是否有Maven/Gradle存储库?
- 28. Fedora 16存储库中是否有Rstudio?
- 29. 获取存储库的所有标签与JGit
- 30. xcode 7.1 subverison存储库验证失败
你可以看看[这个答案](http://stackoverflow.com/a/13606879/640012)。我认为这正是你想要的。 – Abhishek
您可以使用JGIT调用'git ls-remote'。请参阅(http://superuser.com/questions/227509/git-ping-check-if-remote-repository-exists) –
Muco