【发布时间】:2015-02-06 07:37:32
【问题描述】:
我试图显示一个文件的两次提交之间的 git diff。基本上,我是按照https://github.com/centic9/jgit-cookbook/blob/master/src/main/java/org/dstadler/jgit/porcelain/ShowChangedFilesBetweenCommits.java
你可以在https://github.com/svenhornberg/JGitDiff下看到我的完整代码
public class RepoDiff {
public void compare(byte[] fileContentOld, byte[] fileContentNew) {
try {
Repository repository = createNewRepository();
Git git = new Git(repository);
// create the file
commitFileContent(fileContentOld, repository, git, true);
commitFileContent(fileContentNew, repository, git, false);
// The {tree} will return the underlying tree-id instead of the commit-id itself!
ObjectId oldHead = repository.resolve("HEAD^^^^{tree}"); //here is my nullpointer
ObjectId head = repository.resolve("HEAD^{tree}");
System.out.println("Printing diff between tree: " + oldHead + " and " + head);
// prepare the two iterators to compute the diff between
ObjectReader reader = repository.newObjectReader();
CanonicalTreeParser oldTreeIter = new CanonicalTreeParser();
oldTreeIter.reset(reader, oldHead);
CanonicalTreeParser newTreeIter = new CanonicalTreeParser();
newTreeIter.reset(reader, head);
// finally get the list of changed files
List<DiffEntry> diffs= new Git(repository).diff()
.setNewTree(newTreeIter)
.setOldTree(oldTreeIter)
.call();
for (DiffEntry entry : diffs) {
System.out.println("Entry: " + entry);
}
System.out.println("Done");
} catch (Exception exception) {
exception.printStackTrace();
}
}
/**
* Adds and optionally commits fileContent to a repository
* @param commit True if file should be committed, False if not
* @throws Exception catch all for testing
*/
private void commitFileContent(byte[] fileContent, Repository repository, Git git, boolean commit) throws Exception {
File myfile = new File(repository.getDirectory().getParent(), "testfile");
myfile.createNewFile();
FileOutputStream fos = new FileOutputStream (myfile);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
baos.write(fileContent);
baos.writeTo(fos);
// run the add
git.add().addFilepattern("testfile").call();
if(commit) {
// and then commit the changes
git.commit().setMessage("Added fileContent").call();
}
fos.close();
}
/**
* Helperfunction from
* https://github.com/centic9/jgit-cookbook
*/
public static Repository createNewRepository() throws IOException {
// prepare a new folder
File localPath = File.createTempFile("TestGitRepository", "");
localPath.delete();
// create the directory
Repository repository = FileRepositoryBuilder.create(new File(
localPath, ".git"));
repository.create();
return repository;
}
}
代码导致此消息:
Printing diff between tree: null and AnyObjectId[c11a3a58c23b0dd6e541c4bcd553197772626bc6]
java.lang.NullPointerException
at org.eclipse.jgit.internal.storage.file.UnpackedObjectCache$Table.index(UnpackedObjectCache.java:146)
at org.eclipse.jgit.internal.storage.file.UnpackedObjectCache$Table.contains(UnpackedObjectCache.java:109)
at org.eclipse.jgit.internal.storage.file.UnpackedObjectCache.isUnpacked(UnpackedObjectCache.java:64)
at org.eclipse.jgit.internal.storage.file.ObjectDirectory.openObject(ObjectDirectory.java:367)
at org.eclipse.jgit.internal.storage.file.WindowCursor.open(WindowCursor.java:145)
at org.eclipse.jgit.treewalk.CanonicalTreeParser.reset(CanonicalTreeParser.java:202)
at javadiff.RepoDiff.compare(RepoDiff.java:40)
at javadiff.GitDiff.main(GitDiff.java:30)
下面这行一定是假的,但和 jgit-cookbook 的例子一样
ObjectId oldHead = repository.resolve("HEAD^^^^{tree}"); //here is my nullpointer
我测试了HEAD^1{Tree} 但这不起作用,看起来{tree} 必须在字符串中才能解析树而不是提交ID。有什么想法让它发挥作用吗?
【问题讨论】:
-
附带说明:
repository.getDirectory().getParent()不一定返回工作目录,请改用repository.getWorkTree()。还有一点注意:你也可以通过git.getRepository()获取repository,这样就可以省掉commitFileContent中的repository参数。