如何定义一个 "In between" JGit RevFilter?
How to define a "In between" JGit RevFilter?
我正在尝试实现一个 RevFilter
以通过 RevWalk#setRevFilter()
使用。以下是我尝试过的内容:
private class InBetweenRevFilter extends RevFilter {
private AnyObjectId end;
private AnyObjectId begin;
public InBetweenRevFilter(AnyObjectId begin, AnyObjectId end) {
this.begin = begin;
this.end = end;
}
@Override
public RevFilter clone() {
return this;
}
@Override
public boolean include(RevWalk walker, RevCommit c)
throws StopWalkException, MissingObjectException,
IncorrectObjectTypeException, IOException {
RevCommit from = walker.parseCommit(begin);
RevCommit to = walker.parseCommit(end);
return (walker.isMergedInto(from, c) && walker.isMergedInto(c, to));
}
}
过滤器的结果应该是在 begin
之后和 end
之前推送的提交。问题是,当我设置此过滤器时,RevWalk.next()
仅返回标记为 RevWalk.markStart(RevCommit c)
起点的提交。在下文中,我展示了我是如何尝试使用过滤器的:
RevWalk walk = new RevWalk(getRepository());
RevCommit beginCommit = walk.parseCommit(getRepository().resolve(start));
RevCommit endCommit = walk.parseCommit(getRepository().resolve(end));
walk.setRevFilter(new InBetweenRevFilter(beginCommit.getId(), endCommit.getId()));
walk.markStart(endCommit);
for (RevCommit rev : walk) {
System.out.println(rev.getFullMessage());
}
walk.close();
在本例中,只有来自 endCommit
的消息打印在控制台中。还有其他方法吗?或者,我错过了什么或做错了什么?
我刚刚在 jgit-cookbook 上发布了一个片段,展示了一种方法:
基本上,您可以从一个提交开始遍历,然后 运行 遍历直到找到第二个或分支上的提交 运行。
请注意,您在这里及时倒退,因为这是 Git 存储提交之间链接的方式,即我们从 "to" 开始,这是较新的提交,一直走到 [=19] =].
String from = "3408efc41a51555d488d30d8a91ea560c5e13311";
String to = "7228de6ebe2a3087118562414061af4e189624c0";
// a RevWalk allows to walk over commits based on some filtering that is defined
try (RevWalk walk = new RevWalk(repository)) {
RevCommit commit = walk.parseCommit(repository.resolve(to));
System.out.println("Walking all commits starting at " + to + " until we find " + from);
walk.markStart(commit);
int count = 0;
for (RevCommit rev : walk) {
System.out.println("Commit: " + rev);
count++;
if(rev.getId().getName().equals(from)) {
System.out.println("Found from, stopping walk");
break;
}
}
System.out.println(count);
walk.dispose();
}
这是我的解决方案,但@centic 的解决方案似乎更简单。
public List<RevCommit> between(String start, String end) throws Exception {
RevWalk walk = new RevWalk(getRepository());
RevCommit beginCommit = walk.parseCommit(getRepository().resolve(start));
RevCommit endCommit = walk.parseCommit(getRepository().resolve(end));
walk.close();
return commitsBetween(beginCommit, endCommit);
}
private List<RevCommit> commitsBetween(RevCommit begin, RevCommit end) throws Exception {
List<RevCommit> commits = new LinkedList<>();
RevWalk walk = new RevWalk(getRepository());
RevCommit parent = walk.parseCommit(end.getParent(0).getId());
if (parent.getName().equals(begin.getName())) {
commits.add(end);
walk.close();
return commits;
} else {
commits.add(end);
commits.addAll(commitsBetween(begin, parent));
walk.close();
return commits;
}
}
更新:
我在 EGit/JGit 论坛中得到了这个 answer,它和@centic 的回答一样简单。
RevCommit begin = getBeginCommit();
RevCommit end = getEndCommit();
try (RevWalk rw = new RevWalk(getRepository())) {
rw.markStart(rw.lookupCommit(begin));
rw.markUninteresting(rw.lookupCommit(end));
for (RevCommit curr; (curr = rw.next()) != null;)
System.out.println("Inspecting entry: " + curr.getShortMessage());
}
我正在尝试实现一个 RevFilter
以通过 RevWalk#setRevFilter()
使用。以下是我尝试过的内容:
private class InBetweenRevFilter extends RevFilter {
private AnyObjectId end;
private AnyObjectId begin;
public InBetweenRevFilter(AnyObjectId begin, AnyObjectId end) {
this.begin = begin;
this.end = end;
}
@Override
public RevFilter clone() {
return this;
}
@Override
public boolean include(RevWalk walker, RevCommit c)
throws StopWalkException, MissingObjectException,
IncorrectObjectTypeException, IOException {
RevCommit from = walker.parseCommit(begin);
RevCommit to = walker.parseCommit(end);
return (walker.isMergedInto(from, c) && walker.isMergedInto(c, to));
}
}
过滤器的结果应该是在 begin
之后和 end
之前推送的提交。问题是,当我设置此过滤器时,RevWalk.next()
仅返回标记为 RevWalk.markStart(RevCommit c)
起点的提交。在下文中,我展示了我是如何尝试使用过滤器的:
RevWalk walk = new RevWalk(getRepository());
RevCommit beginCommit = walk.parseCommit(getRepository().resolve(start));
RevCommit endCommit = walk.parseCommit(getRepository().resolve(end));
walk.setRevFilter(new InBetweenRevFilter(beginCommit.getId(), endCommit.getId()));
walk.markStart(endCommit);
for (RevCommit rev : walk) {
System.out.println(rev.getFullMessage());
}
walk.close();
在本例中,只有来自 endCommit
的消息打印在控制台中。还有其他方法吗?或者,我错过了什么或做错了什么?
我刚刚在 jgit-cookbook 上发布了一个片段,展示了一种方法:
基本上,您可以从一个提交开始遍历,然后 运行 遍历直到找到第二个或分支上的提交 运行。
请注意,您在这里及时倒退,因为这是 Git 存储提交之间链接的方式,即我们从 "to" 开始,这是较新的提交,一直走到 [=19] =].
String from = "3408efc41a51555d488d30d8a91ea560c5e13311";
String to = "7228de6ebe2a3087118562414061af4e189624c0";
// a RevWalk allows to walk over commits based on some filtering that is defined
try (RevWalk walk = new RevWalk(repository)) {
RevCommit commit = walk.parseCommit(repository.resolve(to));
System.out.println("Walking all commits starting at " + to + " until we find " + from);
walk.markStart(commit);
int count = 0;
for (RevCommit rev : walk) {
System.out.println("Commit: " + rev);
count++;
if(rev.getId().getName().equals(from)) {
System.out.println("Found from, stopping walk");
break;
}
}
System.out.println(count);
walk.dispose();
}
这是我的解决方案,但@centic 的解决方案似乎更简单。
public List<RevCommit> between(String start, String end) throws Exception {
RevWalk walk = new RevWalk(getRepository());
RevCommit beginCommit = walk.parseCommit(getRepository().resolve(start));
RevCommit endCommit = walk.parseCommit(getRepository().resolve(end));
walk.close();
return commitsBetween(beginCommit, endCommit);
}
private List<RevCommit> commitsBetween(RevCommit begin, RevCommit end) throws Exception {
List<RevCommit> commits = new LinkedList<>();
RevWalk walk = new RevWalk(getRepository());
RevCommit parent = walk.parseCommit(end.getParent(0).getId());
if (parent.getName().equals(begin.getName())) {
commits.add(end);
walk.close();
return commits;
} else {
commits.add(end);
commits.addAll(commitsBetween(begin, parent));
walk.close();
return commits;
}
}
更新: 我在 EGit/JGit 论坛中得到了这个 answer,它和@centic 的回答一样简单。
RevCommit begin = getBeginCommit();
RevCommit end = getEndCommit();
try (RevWalk rw = new RevWalk(getRepository())) {
rw.markStart(rw.lookupCommit(begin));
rw.markUninteresting(rw.lookupCommit(end));
for (RevCommit curr; (curr = rw.next()) != null;)
System.out.println("Inspecting entry: " + curr.getShortMessage());
}