2014-09-28 91 views
1

我正在尝试将子模块支持添加到project of mine,但我似乎无法使用JGit读取特定的提交或记录,而命令行git可以做到这一点,尽管分离首先说明子模块在哪里(就设计子模块的工作而言)。JGit:从子模块读取提交

我有这样的代码,以“熔断器人民军”是子模块:

FileRepositoryBuilder builder = new FileRepositoryBuilder(); 
    Repository repository = builder.setGitDir(new File("fuse-jna/.git")) 
     .readEnvironment() // scan environment GIT_* variables 
     .findGitDir() // scan up the file system tree 
     .build(); 

    ObjectId lastCommitId = repository.resolve("39c1c4b78ff751b0b9e28f4fb35148a1acd6646f"); 

    Iterable<RevCommit> commits = new Git(repository).log().add(lastCommitId).call(); 
    for(RevCommit commit : commits) { 
     System.out.println("Commit: " + commit.getId()); 
    } 

这个我得到:

org.eclipse.jgit.errors.MissingObjectException: Missing commit 39c1c4b78ff751b0b9e28f4fb35148a1acd6646f 
at org.eclipse.jgit.internal.storage.file.WindowCursor.open(WindowCursor.java:149) 
at org.eclipse.jgit.revwalk.RevWalk.getCachedBytes(RevWalk.java:883) 
at org.eclipse.jgit.revwalk.RevCommit.parseHeaders(RevCommit.java:145) 
at org.eclipse.jgit.revwalk.RevWalk.markStart(RevWalk.java:279) 
at org.eclipse.jgit.api.LogCommand.add(LogCommand.java:330) 
at org.eclipse.jgit.api.LogCommand.add(LogCommand.java:189) 
at org.dstadler.jgitfs.util.JGitHelperTest.testGitLinkRepository(JGitHelperTest.java:638) 

但是在命令行中的“保险丝南斯拉夫人民军”目录

git diff 39c1c4b78ff751b0b9e28f4fb35148a1acd6646f~ 

工作得很好,所以有可能这样做。

有没有其他方法如何与JGit做到这一点?或者是不完全支持子模块呢?

+0

仅供参考,同样使用内部的“git的/模块/熔断器JNA/git的”不工作。此外,“repository.getAllRefs()”也会返回一个空列表,所以在这里根本找不到参考... – centic 2014-09-28 22:07:47

+0

我不知道JGit是如何工作的,但是关于子模块,它们基本上都是自己的仓库。在命令行中,当你在子模块的目录中时,你也只能看到他们的提交。使用JGit,你是从子模块的目录还是主存储库的目录中尝试它? – rednaw 2014-09-28 22:15:40

+0

在代码中列出的代码中,我试图像普通的Git仓库一样打开子模块库,但这似乎不是JGit在这里需要的,请参阅下面的自我回答。 – centic 2014-09-28 22:43:56

回答

1

似乎诀窍是不像常规Git存储库那样打开子模块的存储库,但使用JGit类SubmoduleWalk和父存储库来执行此操作!

以下为我所做的工作,玩了多一些后:

 Repository subRepo = SubmoduleWalk.getSubmoduleRepository(repository, "fuse-jna"); 
+1

尽管'SubmoduleWalk.getSubmoduleRepository'工作得很好,我想澄清一下_Why_ FileRepositoryBuilder方法失败:'setGitDir()'调用指定一个*相对路径*(对应用程序的工作目录)。如果更改为'setGitDir(new File(parentRepo.getWorkTree(),“fuse-jna/.git”))'sub-repository也会被找到。如果你看看'getSubmoduleRepository()',你会发现那里使用了类似的代码。 – 2014-09-29 08:16:26

+0

非常感谢你的额外解释,似乎我没有在这里读到足够的存储库生成器类,细节似乎隐藏在代码中,setGitDir()在我所有其他用例中工作到目前为止,而setWorkTree ()可能是一个更好的选择对于大多数情况下... – centic 2014-09-29 12:31:46

+0

我仍然建议[首选setGitDir()通过setWorkDir](http://www.codeaffine.com/2014/09/22/access-git-repository-与-jgit /)。你问题的代码片段中的错误是使用相对路径(“fuse-jna/.git”)而不是绝对路径(“/path/to/parent-repo/fuse-jna/.git”)。相对路径相对于您的**程序的工作目录**进行解释(不要与存储库工作目录混淆),也不适用于setWorkDir()。 – 2014-09-29 13:22:10