使用JGit获取存储库中的最新提交

时间:2017-03-15 20:41:17

标签: java git jgit

我想使用JGit在存储库中获取最后一次提交元数据(按日​​期最年轻的提交元数据)。

我知道我可以使用

获取提交元数据
try (RevWalk walk = new RevWalk(repository)) {
    RevCommit commit = walk.parseCommit(repository.resolve(commitHash));
}

但是如何获取最新的提交哈希?

还有其他方法可以直接在存储库中获取最年轻的RevCommit吗?

4 个答案:

答案 0 :(得分:2)

要查找存储库中的最新提交,请将RevWalk配置为从所有已知引用开始,并按提交日期降序排序。例如:

Repository repo = ...
try( RevWalk revWalk = new RevWalk( repo ) ) {
  revWalk.sort( RevSort.COMMIT_TIME_DESC );
  Map<String, Ref> allRefs = repo.getRefDatabase().getRefs( RefDatabase.ALL );
  for( Ref ref : allRefs.values() ) {
    RevCommit commit = revWalk.parseCommit( ref.getLeaf().getObjectId() );
    revWalk.markStart( commit );
  }
  RevCommit newestCommit = revWalk.next();
}

根据您的使用情况,您可能还需要标记来自repo.getRefDatabase().getAdditionalRefs()的引号的起点,其中包括FETCH_RESULTORIG_HEAD等参考号。如果您发现仍然存在未经跟踪的裁判,请使用repo.getRefDatabase().getRef()

答案 1 :(得分:1)

比较所有分支中的最后提交日期。 ListMode.ALL可以更改为ListMode.REMOTE,仅比较远程分支。 或者......可以省略流畅的setter .setListMode(whatever)以从本地存储库中读取。

RevCommit youngestCommit = null;    
List<Ref> branches = new Git(repository).branchList().setListMode(ListMode.ALL).call();
try(RevWalk walk = new RevWalk(git.getRepository())) {
    for(Ref branch : branches) {
        RevCommit commit = walk.parseCommit(branch.getObjectId());
        if(commit.getAuthorIdent().getWhen().compareTo(
           youngestCommit.getAuthorIdent().getWhen()) > 0)
           youngestCommit = commit;
    }
}

答案 2 :(得分:1)

您可以在下面找到 Java 8 Stream API 解决方案:

final List<Ref> branches = git.branchList().setListMode(ListBranchCommand.ListMode.ALL).call();
final RevWalk revWalk = new RevWalk(git.getRepository());

branches.stream()
        .map(branch -> {
            try {
                return revWalk.parseCommit(branch.getObjectId());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        })
        .sorted(Comparator.comparing((RevCommit commit) -> commit.getAuthorIdent().getWhen()).reversed())
        .findFirst()
        .ifPresent(commit -> {
            System.out.printf("%s: %s (%s)%n", commit.getAuthorIdent().getWhen(), commit.getShortMessage(), commit.getAuthorIdent().getName());
        });

它遍历所有分支并在这些分支中选择最近的提交,然后按照后代顺序按日期排序提交列表并选择第一个。如果它存在,它将打印到控制台输出,如下所示:

Wed Aug 30 09:49:42 CEST 2017: test file added (Szymon Stepniak)

当然,上次提交存在的行为是示例性的,可以很容易地用任何其他业务逻辑替换。我希望它有所帮助。

答案 3 :(得分:0)

您可以使用git log并将其设置为仅返回最上面的提交:

RevCommit latestCommit = new Git(repository).log().setMaxCount(1).call().iterator().next;

String latestCommitHash = latestCommit.getName();