Get the latest commit in a repository with JGit

眉间皱痕 提交于 2019-12-01 19:35:36
Grzegorz Górkiewicz

Compare by dates of last commits in all branches. ListMode.ALL can be changed to ListMode.REMOTE to compare only remote branches. Or... the fluent setter .setListMode(whatever) can be omitted to read from the local repository.

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(yougestCommit == null || commit.getAuthorIdent().getWhen().compareTo(
           youngestCommit.getAuthorIdent().getWhen()) > 0)
           youngestCommit = commit;
    }
}

To find the newest commit within a repository, configure a RevWalk to start from all known refs and sort it descending by commit date. For example:

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();
}

Depending on your use case, you may also want to mark start points from refs from repo.getRefDatabase().getAdditionalRefs() which includes refs like FETCH_RESULT, ORIG_HEAD, etc. If you find that there are still untracked refs, use repo.getRefDatabase().getRef().

Below you can find a Java 8 Stream API solution:

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());
        });

It iterates over all branches and picks recent commits in those branches, then it sorts list of commits by date in descendant order and picks the first one. If it exists it prints to console output something like this:

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

Of course the behavior on last commit existence is exemplary and it can be easily replaced with any additional business logic. I hope it helps.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!