Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/spring-boot/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JGit:RevWalk订单覆盖起点_Java_Jgit - Fatal编程技术网

Java JGit:RevWalk订单覆盖起点

Java JGit:RevWalk订单覆盖起点,java,jgit,Java,Jgit,我在我的一个项目中使用JGit,该项目涉及git的智能化使用 我的目标是使用RevWalk,以便能够按照时间顺序在存储库中的提交上迭代,从特定的提交开始。我成功地分别实现了这两个目标: 通过应用RevSort.REVERSE 通过调用RevWalk.markStart(RevCommit c) 我的问题是,当我尝试将两者结合起来时,似乎RevSort覆盖了markStart,而RevWalk总是在提交的开始处开始,而不是我指定的提交的开始处 这段代码显示了我得到的: import org.e

我在我的一个项目中使用JGit,该项目涉及git的智能化使用

我的目标是使用
RevWalk
,以便能够按照时间顺序在存储库中的提交上迭代,从特定的提交开始。我成功地分别实现了这两个目标:

  • 通过应用
    RevSort.REVERSE
  • 通过调用
    RevWalk.markStart(RevCommit c)
我的问题是,当我尝试将两者结合起来时,似乎RevSort覆盖了markStart,而RevWalk总是在提交的开始处开始,而不是我指定的提交的开始处

这段代码显示了我得到的:

import org.eclipse.jgit.lib.Repository;
导入org.eclipse.jgit.internal.storage.file.FileRepository;
导入org.eclipse.jgit.revwalk.revwalk;
导入org.eclipse.jgit.revwalk.RevCommit;
导入org.eclipse.jgit.revwalk.RevSort;
导入java.io.IOException;
导入org.eclipse.jgit.errors.AmbiguousObjectException;
导入org.eclipse.jgit.errors.MissingObjectException;
公共班机{
公共静态void main(字符串[]args)引发IOException、AmbiguousObjectException、MissingObjectException{
最终字符串repositoryPath=args[0];
最终字符串commitID=args[1];
最终存储库=新文件存储库(repositoryPath+“/.git”);
最终RevWalk=新RevWalk(存储库);
walk.sort(RevSort.REVERSE);
markStart(walk.parseCommit(repository.resolve(commitID));
对于(最终RevCommit RevCommit:walk){
System.err.println(revCommit.getId());
}
}
}
这应该从指定的提交开始,以相反的顺序打印存储库的ID,但它只是忽略第二个设置,并从初始提交开始

更新:

我对这个问题进行了更多的研究,结果表明,当同时应用这两个选项(以任何顺序)时,
markStart
变成了
markStop
。我认为这是由于总是首先执行markStart并限制提交的范围(使用过滤器),然后通过
RevSort
将提交的范围反转。基本上,
RevWalk
是对我感兴趣的补充提交集进行迭代

我是否应该假设我试图做的事情无法通过这种方式获得?如果不遍历整个存储库直到我的起点,我想不出其他方法来获取它,但这听起来效率非常低

更新2: 在这里举一个恰当的例子是我期望达到的目标。 假设我们有一个包含4个提交的存储库:a、B、C和D。 我只对B对当前版本的评论感兴趣,不包括A,按时间顺序排列。我希望能够使用
markStart
sort
通过以下方式实现这一点:

@Test
public void testReverse2() throws Exception {
    final RevCommit commitA = this.git.commit().setMessage("Commit A").call();
    final RevCommit commitB = this.git.commit().setMessage("Commit B").call();
    final RevCommit commitC = this.git.commit().setMessage("Commit C").call();
    final RevCommit commitD = this.git.commit().setMessage("Commit D").call();

    final RevWalk revWalk = new RevWalk(this.git.getRepository());
    revWalk.markStart(revWalk.parseCommit(commitB));
    revWalk.sort(RevSort.REVERSE);

    assertEquals(commitB, revWalk.next());
    assertEquals(commitC, revWalk.next());
    assertEquals(commitD, revWalk.next());
    assertNull(revWalk.next());
    revWalk.close();
}
现在,据我所见,这不起作用,因为
markStart
总是在
排序之前执行,因此实际行为满足以下测试:

assertEquals(commitA, revWalk.next());
assertEquals(commitB, revWalk.next());
assertNull(revWalk.next());
这与我想要得到的正好相反。
这是一种有意的行为吗?如果是,我可以用什么其他方式来解决这个问题?

JGit API没有禁止将sort和markStart结合起来。JGit源代码也没有表面问题。在我看来,直接修复这个问题需要源代码级调试。您需要JGit源代码,并且需要在调试器中运行示例

或者,您也可以使用拆分器将RevWalk流式处理,而不使用排序,以在RevCommit:getCommitTime()上比较排序后的输出,如下所示:

StreamSupport.stream(walk.spliterator())
    .sorted(RevCommit::getCommitTime())
    .toList();

在Git中,提交仅具有指向其父级的链接
commitB
不知道其继任者
commitC
commitD

因此,历史只能向后遍历,从给定的提交到它的父级、父级等。没有相反方向的信息可以遍历

在您的示例中,
RevWalk
将从
commitB
移动到
commitÀ
。反向排序只会影响迭代器的行为,但不能向前移动


如果您确实希望在
commitB
HEAD
之间查找提交,则需要从
HEAD
开始。或者,更一般地说,您需要从所有已知的分支提示开始查找可能导致
commitB

的多个路径是的,我已经对源代码进行了更深入的调查并更新了原始帖子。@vivianig感谢您的更新。我认为你可能不得不接受这种代价高昂的做法。我的遍历会访问更多的Git存储库而不是sort吗?它最终可能是等价的。每个方法需要多少时间(没有markStart)?我上面的解决方案应该在调用markStart后使用walk来直接反映您的意图。它可能最终是等效的,因为它仍然需要运行整个存储库才能到达给定的点。我的问题是
markStart
的工作方式,我不认为改变迭代过滤提交集的方式会有所帮助。我稍后会详细讨论。假设我只对一个分支感兴趣,那么从
commitB
HEAD
的最佳方式是什么(保持时间顺序)?我目前的方法是使用
sort
,从一开始就走了一整段路,手动确定到达我想要设置为
start
的点的位置。但这感觉很低效,还有其他方法吗?重新考虑提交如何在Git中相互引用。没有其他方法:从头部开始(即您知道的
commitB
可以到达的点),然后一直走到找到所需的提交。我不明白这是为什么