'Get the latest commit in a repository with JGit

I want to get the last commit metadata (the youngest one by date) in a repository using JGit.

I know that I can get the commit metadata using:

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

But how to get the latest commit hash?

Is there any other way to get the youngest by date RevCommit in a repository directly?



Solution 1:[1]

You could make use of git log and set it to only return the top most commit:

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

String latestCommitHash = latestCommit.getName();

Solution 2:[2]

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().

Solution 3:[3]

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.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Nathan
Solution 2 Rüdiger Herrmann
Solution 3 Szymon Stepniak