Get the latest commit in a repository with JGit

可紊 提交于 2019-12-20 01:17:47

问题


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?


回答1:


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



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




回答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.




回答4:


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


来源:https://stackoverflow.com/questions/42820282/get-the-latest-commit-in-a-repository-with-jgit

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