我试图显示文件的两次提交之间的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)
下面的行必须为false,但这类似于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/
问题内容: 我想在两次提交之间更改(添加,修改或删除)文件的路径。 在命令行中,我只需编写 用JGit执行此操作的等效方法是什么? 问题答案: 您可以使用来获取的列表。每个条目都有一个changeType,用于指定是添加,删除还是更改文件。一个S’ 和方法返回的路径名。该JavaDoc中列出了每个方法retuns对于给定的变型。 上面的示例列出了与其之间的更改文件,但可以进行更改以比较诸如的任意提
我需要使用JGit获取与特定提交关联的分支的名称。我使用JGit获取存储库的提交SHA的完整列表,现在我需要知道它所属的分支的名称。 如果有人能让我知道我如何做到这一点,我将不胜感激。
问题内容: 我一直在研究将要集成Git功能的基于Java的产品。使用Git的功能之一,我通过分阶段执行将10多个文件添加到Git存储库中,然后在一次提交中提交了这些文件。 以上过程可能相反吗?即查找作为提交的一部分提交的文件列表。 我在命令的帮助下获得了提交,但是我不确定如何获取提交的文件列表。 示例代码: 问题答案: 每个提交都指向一 棵树 ,该 树 表示构成该提交的所有文件。注意,这不仅包括使
我一直在开发一个基于Java的产品,Git特性将被集成到该产品中。通过使用Git的一个特性,我将10个文件添加到Git存储库中,然后在一次提交中提交。 上述过程是否可能相反?即查找作为提交的一部分提交的文件列表。 我在< code>git.log()命令的帮助下获得了提交,但是我不确定如何获得提交的文件列表。 示例代码:
问题内容: 在连接到仓库以及添加,提交甚至循环提交文件的消息方面,我已经设法掌握了jGit文件的基础知识。 我接下来要做的是能够获取单个文件的所有提交消息,然后能够将单个文件还原回特定的参考/时间点。 问题答案: 这是基于所有父提交查找提交更改的方法 (标量代码) 请注意,TreeFilter.ANY_DIFF适用于单个树遍历器,并将返回根提交中可用的所有元素。 然后,您将不得不遍历树以查看您的文
问题内容: 这在IE中不起作用: 它显示一个方形按钮。 问题答案: 从此链接复制后,您可以使按钮看起来像一个链接-