java - Jgit比较更改返回null
问题描述
我正在尝试提交一个文件并比较两次提交之间的文件更改。我试过下面的代码
public void changes() throws IOException, GitAPIException {
FileRepositoryBuilder builder = new FileRepositoryBuilder();
repo = builder.setGitDir(new File("D:/Gitrepo" + "/.git")).setMustExist(true)
.build();
git = new Git(repo);
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() );
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();
}
当我执行上述代码时,我将输出作为 DiffEntry[MODIFY file.txt] 而不是获取文件内容差异。(即第一版和第二版)。
所以我尝试使用下面的哈希码比较内容
listDiff(repo, git, "b7ed64bb0356bf0e0a1d0b01fd7cd178deca01f5",
"e33dad5cbbf848bff3000b85acd9f5f9bd04102c");
private static void listDiff(Repository repository, Git git, String oldCommit, String newCommit) throws GitAPIException, IOException {
final List<DiffEntry> diffs = git.diff()
.setOldTree(prepareTreeParser(repository, oldCommit))
.setNewTree(prepareTreeParser(repository, newCommit))
.call();
System.out.println("Found: " + diffs.size() + " differences");
for (DiffEntry diff : diffs) {
System.out.println("Diff: " + diff.getChangeType() + ": " +
(diff.getOldPath().equals(diff.getNewPath()) ? diff.getNewPath() : diff.getOldPath() + " -> " + diff.getNewPath()));
}
}
private static AbstractTreeIterator prepareTreeParser(Repository repository, String objectId) throws IOException {
// from the commit we can build the tree which allows us to construct the TreeParser
//noinspection Duplicates
try (RevWalk walk = new RevWalk(repository)) {
RevCommit commit = walk.parseCommit(repository.resolve(objectId));
RevTree tree = walk.parseTree(commit.getTree().getId());
CanonicalTreeParser treeParser = new CanonicalTreeParser();
try (ObjectReader reader = repository.newObjectReader()) {
treeParser.reset(reader, tree.getId());
}
walk.dispose();
return treeParser;
}
}
但这也不起作用,它返回 Diff: 0 我从“D:\Gitrepo.git\logs\refs\heads\master”中获取了哈希码。请纠正我哪里出错了
解决方案
我已经通过改革如下代码解决了这个问题
public static void main(String[] args) throws Exception {
Repository repository = new FileRepositoryBuilder()
.setGitDir(new File("D:/Gitrepo/.git")).build();
RevCommit headCommit = getHeadCommit(repository);
RevCommit diffWith = headCommit.getParent(0);
FileOutputStream stdout = new FileOutputStream(FileDescriptor.out);
try (DiffFormatter diffFormatter = new DiffFormatter(stdout)) {
diffFormatter.setRepository(repository);
for (DiffEntry entry : diffFormatter.scan(diffWith, headCommit)) {
diffFormatter.format(diffFormatter.toFileHeader(entry));
}
}
}
private static RevCommit getHeadCommit(Repository repository) throws Exception {
try (Git git = new Git(repository)) {
Iterable<RevCommit> history = git.log().setMaxCount(1).call();
return history.iterator().next();
}
}
它打印文件的内容,如下所示
diff --git a/file.txt b/file.txt
index bde942a..506150f 100644
--- a/file.txt
+++ b/file.txt
@@ -1 +1 @@
-first version
\ No newline at end of file
+second version
\ No newline at end of file
感谢@Rüdiger Herrmann 的指导
推荐阅读
- tsql - 根据 SSRS 中所有记录的聚合设置组的值
- elasticsearch - Grafana Elastic-Datasource 找不到时间字段
- angular - 样条图系列未在导出为图像时打印
- google-apps-script - Google Sheets 脚本和 Google Sheets API 有什么区别?
- r - summarise_all,计数 n() 失败
- php - 如何使用 textlocal sms api 在 Codeigniter 中发送 OTP?
- codenameone - Codenameone - Picker 如何控制午夜显示 12(小时)
- html - 应用 margin-left 后右边框丢失
- amazon-web-services - Amazon CodeDeploy ApplicationStop 脚本无论如何都会失败
- selenium - 我如何使用 POM 和 Testng 在 selenium 的所有页面上传输相同的驱动程序组件