如何修复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
相关产品推荐
相关产品推荐

