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

Get the latest commit in a repository with JGit

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

我知道我可以使用以下方法获取提交元数据:

try (RevWalk walk = new RevWalk(repository))
{
    RevCommit commit = walk.parseCommit(repository.resolve(commitHash));
}

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

有没有其他方法可以直接在存储库中按日期 RevCommit 获取最小的?

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

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

要在存储库中查找最新提交,请配置 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().

您可以在下方找到 Java 8 流 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)

当然,最后一次提交存在时的行为堪称典范,可以很容易地用任何其他业务逻辑替换。希望对你有帮助。

您可以使用 git log 并将其设置为仅 return 最高提交:

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

String latestCommitHash = latestCommit.getName();