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

如何修复jGit获取冲突文件ObjectId的代码?

修复JGit获取冲突文件两个版本的代码问题

问题背景

使用JGit的status()命令列出冲突文件后,尝试加载处于CONFLICTING状态文件的本地版本(STAGE_2)和远程版本(STAGE_3),但原代码中DirCache.getEntry()方法仅接受文件路径单个参数,不再支持传入stage参数,导致代码无法运行。

修复后的完整代码

import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.Status;
import org.eclipse.jgit.dircache.DirCache;
import org.eclipse.jgit.dircache.DirCacheEntry;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectLoader;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.storage.file.FileRepositoryBuilder;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.Set;

public class JGitConflictObjectIds {
    public static void main(String[] args) throws IOException {
        try (Repository repository = new FileRepositoryBuilder().setGitDir(new File("/path/to/repo/.git")).build()) {
            Git git = new Git(repository);
            Status status = git.status().call();

            Set<String> conflictingFiles = status.getConflicting();
            for (String filePath : conflictingFiles) {
                DirCache dirCache = repository.readDirCache();
                DirCacheEntry ourEntry = null;
                DirCacheEntry theirEntry = null;

                // 遍历目录缓存条目,筛选对应文件的不同stage版本
                int entryIndex = dirCache.findEntry(filePath);
                if (entryIndex >= 0) {
                    DirCacheEntry entry = dirCache.getEntry(entryIndex);
                    // 同一个文件可能有多个stage条目,循环查找
                    while (entry != null && entry.getPathString().equals(filePath)) {
                        int stage = entry.getStage();
                        if (stage == DirCacheEntry.STAGE_2) {
                            ourEntry = entry;
                        } else if (stage == DirCacheEntry.STAGE_3) {
                            theirEntry = entry;
                        }
                        entryIndex++;
                        if (entryIndex >= dirCache.getEntryCount()) {
                            break;
                        }
                        entry = dirCache.getEntry(entryIndex);
                    }
                }

                if (ourEntry == null || theirEntry == null) {
                    System.out.println("未找到文件" + filePath + "的冲突版本");
                    continue;
                }

                ObjectId ourId = ourEntry.getObjectId();
                ObjectId theirId = theirEntry.getObjectId();

                System.out.println("文件: " + filePath);
                System.out.println("本地版本ObjectId: " + ourId.name());
                System.out.println("远程版本ObjectId: " + theirId.name());

                String ourContent = readBlobContent(repository, ourId);
                String theirContent = readBlobContent(repository, theirId);

                System.out.println("本地版本内容:\n" + ourContent);
                System.out.println("远程版本内容:\n" + theirContent);
            }
        }
    }

    /**
     * 直接读取Blob对象的内容
     * @param repository Git仓库对象
     * @param blobId Blob的ObjectId
     * @return 文件内容字符串
     * @throws IOException IO异常
     */
    private static String readBlobContent(Repository repository, ObjectId blobId) throws IOException {
        ObjectLoader loader = repository.open(blobId);
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        loader.copyTo(out);
        return out.toString();
    }
}

关键修改说明

  • 替换DirCache.getEntry()的多参数调用:
    先用dirCache.findEntry(filePath)定位文件的起始条目索引,再循环遍历后续条目,通过entry.getStage()区分版本阶段:STAGE_2对应本地分支版本,STAGE_3对应合并的远程分支版本。
  • 修复文件内容读取逻辑:
    原方法错误地将Blob的ObjectId当作CommitId处理,改为直接通过repository.open(blobId)读取Blob内容,简化逻辑并避免错误。
  • 增加异常防护:
    加入对ourEntry和theirEntry的空值检查,避免因未找到对应版本导致的空指针异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 13:21:13