如何在JGit的RevCommit中查看未追踪文件以正确展示stash内容?
解决方案
问题根因
默认stash不会存储未追踪文件,且包含未追踪文件的stash为3父提交结构,默认的diff逻辑仅对比stash和对应的HEAD父节点,不会读取第三个专门存储未追踪文件的父节点内容,因此无法展示未追踪文件。
操作步骤
- 第一步:创建stash时开启未追踪文件包含
使用JGit的StashCreateCommand生成stash时,需添加setIncludeUntracked(true)配置,代码示例:
RevCommit stashCommit = git.stashCreate() .setIncludeUntracked(true) // 核心配置,开启未追踪文件存储 .setMessage("stash备注内容") .call();
开启该配置后生成的stash提交会包含3个父节点:第1个为当前HEAD提交、第2个为暂存区提交、第3个为未追踪文件的专属提交。
- 第二步:拆分diff逻辑,分别读取常规修改和未追踪文件
获取到stash对应的RevCommit对象后,分两部分执行diff即可拿到全量变更:
- 常规修改文件diff:沿用原有逻辑,对比stash提交和第1个父节点(HEAD)的树即可。
- 未追踪文件diff:对比第3个父节点和Git内置空树,即可拿到所有未追踪文件的diff内容,核心代码示例:
// 获取Git内置空树的树对象 ObjectId emptyTreeId = repository.resolve("4b825dc642cb6eb9a060e54bf8d69288fbee4904"); RevTree emptyTree = revWalk.parseTree(emptyTreeId); // 判断当前stash是否包含未追踪文件 if (stashCommit.getParentCount() == 3) { RevCommit untrackedParent = stashCommit.getParent(2); // 执行diff对比空树和未追踪文件父节点的树 List<DiffEntry> untrackedDiffs = git.diff() .setOldTree(emptyTree) .setNewTree(untrackedParent.getTree()) .call(); // 遍历untrackedDiffs即可拿到所有未追踪文件的变更信息 }
注意事项
如果创建stash时未开启includeUntracked配置,stash提交的父节点数为2,不存在存储未追踪文件的父节点,此时无法查询到未追踪文件属于正常行为。
内容的提问来源于stack exchange,提问作者maul
相关产品推荐
相关产品推荐

