gpt4 book ai didi

java - 如何使用 JGit 显示提交之间的更改

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:41:45 26 4
gpt4 key购买 nike

我正在尝试显示一个文件的两次提交之间的 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。有什么想法让它发挥作用吗?

最佳答案

要获取头部提交的树,调用

git.getRepository().resolve( "HEAD^{tree}" )

要获取 HEAD 提交的父级树,请调用

git.getRepository().resolve( "HEAD~1^{tree}" )

如果您对更多详细信息感兴趣,请搜索“Git caret and tilde”。

总而言之,这里有一段计算两个提交差异的代码段:

File file = new File( git.getRepository().getWorkTree(), "file.txt" );
writeFile( file, "first version" );
RevCommit newCommit = commitChanges();
writeFile( file, "second version" );
RevCommit oldCommit = commitChanges();

ObjectReader reader = git.getRepository().newObjectReader();
CanonicalTreeParser oldTreeIter = new CanonicalTreeParser();
ObjectId oldTree = git.getRepository().resolve( "HEAD^{tree}" ); // equals newCommit.getTree()
oldTreeIter.reset( reader, oldTree );
CanonicalTreeParser newTreeIter = new CanonicalTreeParser();
ObjectId newTree = git.getRepository().resolve( "HEAD~1^{tree}" ); // equals oldCommit.getTree()
newTreeIter.reset( reader, newTree );

DiffFormatter df = new DiffFormatter( new ByteArrayOutputStream() ); // use NullOutputStream.INSTANCE if you don't need the diff output
df.setRepository( git.getRepository() );
List<DiffEntry> entries = df.scan( oldTreeIter, newTreeIter );

for( DiffEntry entry : entries ) {
System.out.println( entry );
}

private RevCommit commitChanges() throws GitAPIException {
git.add().addFilepattern( "." ).call();
return git.commit().setMessage( "commit message" ).call();
}

private static void writeFile( File file, String content ) throws IOException {
FileOutputStream outputStream = new FileOutputStream( file );
outputStream.write( content.getBytes( "UTF-8" ) );
outputStream.close();
}

关于显示提交之间的变化的进一步考虑,您可能需要阅读对 JGit 差异 API 的深入讨论,可以在此处找到:http://www.codeaffine.com/2016/06/16/jgit-diff/

关于java - 如何使用 JGit 显示提交之间的更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27361538/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com