You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Java程序中使用JGit列出修改指定目录的所有Git提交

使用JGit列出修改指定目录文件的所有提交

核心实现思路

通过JGit的RevWalk遍历仓库提交,对每个提交做以下检查:

  • 若为初始提交(无父提交),直接遍历提交树中的所有文件,判断是否存在目标目录下的文件
  • 若有父提交,对比当前提交与父提交的差异,检查变更文件的路径是否包含目标目录

完整代码示例

import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.diff.DiffEntry;
import org.eclipse.jgit.diff.DiffFormatter;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevSort;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.treewalk.TreeWalk;
import org.eclipse.jgit.util.io.DisabledOutputStream;

import java.io.File;
import java.util.List;

public class GitCommitScanner {
    public static void main(String[] args) throws Exception {
        // 替换为你的仓库路径
        String repoPath = "/path/to/your/repository";
        // 替换为目标目录,注意末尾加斜杠确保匹配目录下的所有文件
        String targetDir = "x/";

        try (Git git = Git.open(new File(repoPath))) {
            Repository repo = git.getRepository();
            try (RevWalk revWalk = new RevWalk(repo)) {
                // 从HEAD开始遍历所有提交
                revWalk.markStart(revWalk.parseCommit(repo.resolve("HEAD")));
                // 可选:设置为从旧到新排序,去掉此行则默认从新到旧
                revWalk.sort(RevSort.REVERSE);

                for (RevCommit commit : revWalk) {
                    boolean affectsTargetDir = false;

                    // 处理初始提交(无父提交)
                    if (commit.getParentCount() == 0) {
                        try (TreeWalk treeWalk = new TreeWalk(repo)) {
                            treeWalk.addTree(commit.getTree());
                            treeWalk.setRecursive(true);
                            while (treeWalk.next()) {
                                String filePath = treeWalk.getPathString();
                                if (filePath.startsWith(targetDir)) {
                                    affectsTargetDir = true;
                                    break;
                                }
                            }
                        }
                    } else {
                        // 对比当前提交与第一个父提交的差异
                        RevCommit parentCommit = revWalk.parseCommit(commit.getParent(0).getId());
                        try (DiffFormatter diffFormatter = new DiffFormatter(DisabledOutputStream.INSTANCE)) {
                            diffFormatter.setRepository(repo);
                            List<DiffEntry> diffEntries = diffFormatter.scan(parentCommit.getTree(), commit.getTree());

                            for (DiffEntry entry : diffEntries) {
                                String filePath = entry.getNewPath();
                                // 处理文件被删除的情况,此时需要检查旧路径
                                if (entry.getChangeType() == DiffEntry.ChangeType.DELETE) {
                                    filePath = entry.getOldPath();
                                }
                                if (filePath.startsWith(targetDir)) {
                                    affectsTargetDir = true;
                                    break;
                                }
                            }
                        }
                    }

                    if (affectsTargetDir) {
                        // 输出符合条件的提交信息,可根据需求调整输出内容
                        System.out.printf("提交ID: %s | 提交时间: %tF %tT | 提交信息: %s%n",
                                commit.getId().abbreviate(7).getName(),
                                commit.getCommitterIdent().getWhen(),
                                commit.getCommitterIdent().getWhen(),
                                commit.getShortMessage());
                    }
                }
            }
        }
    }
}

关键注意事项

  • 目录路径匹配:目标目录targetDir必须以斜杠结尾,避免误匹配类似x_other/file.txt这类名称相似的路径
  • 删除文件处理:当文件被删除时,DiffEntry的newPath会是/dev/null,此时需要通过oldPath判断是否属于目标目录
  • 资源管理:所有实现AutoCloseable的JGit类(如RevWalk、TreeWalk)都用try-with-resources包裹,避免资源泄漏
  • 遍历顺序:默认从最新提交往旧提交遍历,添加revWalk.sort(RevSort.REVERSE)可改为从旧到新顺序

内容的提问来源于stack exchange,提问作者JF Meier

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 03:55:22