如何用JGit实现git log origin/<branch>..HEAD的等价查询功能?
git log origin/<branch>..HEAD的JGit等价功能 我来帮你搞定这个JGit的问题!首先咱们先明确:你用git log origin/<branch>..HEAD是想列出本地HEAD比远程origin/<branch>多出来的所有提交(也就是还没推送到远程的本地提交)。你的JGit代码之所以跑不通,是因为resolve()方法并不支持这种..范围格式的引用,JGit有专门的API来处理提交范围查询。
先回顾你原有的命令与输出
你在cmd里执行的命令:
git log origin/<branch>..HEAD
得到的输出(其中less错误是因为Windows环境默认没有less分页工具,不影响提交信息的获取):
error: cannot spawn less: No such file or directory
commit 436ab1eca3dfxxxxxxxxx569427f51badf2
Author: Chawla, Anukriti Date: Fri May 11 13:38:37 2018 +0530
Committed on : Fri May 11 13:38:37 IST 2018
正确的JGit实现方式
JGit的LogCommand需要通过addRange()方法指定提交范围的起点和终点,而不是直接用resolve()处理..格式。下面是可以正常运行的代码示例,我会一步步解释:
try (Git git = Git.open(new File("/path/to/your/repository"))) { Repository repo = git.getRepository(); // 获取远程分支origin/<branch>对应的提交对象 ObjectId originBranchId = repo.resolve("origin/<branch>"); RevCommit originCommit = repo.parseCommit(originBranchId); // 获取本地HEAD对应的提交对象 ObjectId headId = repo.resolve("HEAD"); RevCommit headCommit = repo.parseCommit(headId); // 查询origin/<branch>到HEAD之间的所有提交(即本地比远程多的提交) Iterable<RevCommit> commits = git.log() .addRange(originCommit, headCommit) .call(); // 遍历输出提交详情 for (RevCommit commit : commits) { System.out.println("Commit ID: " + commit.getName()); System.out.println("Author: " + commit.getAuthorIdent().getName() + " " + commit.getAuthorIdent().getWhen()); System.out.println("Commit Time: " + commit.getCommitterIdent().getWhen()); System.out.println("Commit Message: " + commit.getShortMessage()); System.out.println("---"); } } catch (IOException | GitAPIException e) { e.printStackTrace(); }
关键说明
为什么不能用
resolve("origin/<branch>..HEAD")?
JGit的resolve()方法只能解析单个引用(比如分支名、提交ID、标签),不支持..这种范围语法,直接使用会返回null或抛出异常,导致后续代码无法执行。addRange()的行为addRange(startCommit, endCommit)会返回所有可以从endCommit回溯到startCommit的提交,但不包含startCommit本身,这和git log origin/<branch>..HEAD的行为完全一致——只显示本地HEAD有但远程分支没有的提交。关于
less错误
这个是Git在Windows环境的小问题,因为默认分页工具less不存在,但JGit不会有这个困扰,它直接返回提交集合,不需要依赖分页工具。
内容的提问来源于stack exchange,提问作者Anu Chawla

