1

I can use JGit to view differences between different commits or different branches, but I don't know how to compare uncommitted files with HEAD. I have searched through the JGit Cookbook, but I still haven't found a solution.

aled
  • 21,330
  • 3
  • 27
  • 34
chineseboy
  • 13
  • 3
  • 1
    I don't know anything about JGit, but from a quick search this looks like it's more difficult than it probably ought to be. I see [this](https://stackoverflow.com/questions/31325613/equivalent-of-git-diff-in-jgit) and [this](https://stackoverflow.com/questions/12987364/how-to-diff-with-two-files-by-jgit-without-creating-repo) which might be useful (the second one might work even if the files aren't tracked, assuming it's not outdated). – Zac Anger Aug 03 '23 at 02:29

2 Answers2

1

In Git, the 'local workspace' is called the working directory. The abstraction to compare files from different sources (working directory, index, commit) in JGit are tree iterators.

Once you created two such iterators, you can diff them. To compare the working directory with the HEAD commit, use something like this:

// Create the HEAD tree iterator
ObjectReader reader = git.getRepository().newObjectReader();
CanonicalTreeParser oldTreeIter = new CanonicalTreeParser();
ObjectId headTree = git.getRepository().resolve( "HEAD^{tree}" );
oldTreeIter.reset( reader, headTree );
// Create the working tree iterator
AbstractTreeIterator newTreeIter = new FileTreeIterator(git.getRepository());

// Either: call the diff command
git.diff()
  .setOldTree(oldTreeIter)
  .setNewTree(newTreeIter)
  .call();
// Or: use the DiffFormatter to list changes
try (DiffFormatter formatter = new DiffFormatter(NullOutputStream.INSTANCE)) {
  formatter.setRepository(git.getRepository());
  List<DiffEntry> entries = formatter.scan(oldTreeIterator, newTreeIterator);
}

JGit's DiffCommand just prints the differences to stdout. Alternatively, DiffFormatter::scan may be used to return DiffEntrys each describing a change to a file.

For more on JGit's diff API you may want to read this article, I've written long ago: https://www.codeaffine.com/2016/06/16/jgit-diff/

Rüdiger Herrmann
  • 20,512
  • 11
  • 62
  • 79
  • Thank you for your feedback. I can use formatter.format(oldTreeIterator, newTreeIterator) to see the modified content. – chineseboy Aug 04 '23 at 01:52
  • FYI, I now added snippets for the different types of diffing to the [jgit-cookbook](https://github.com/centic9/jgit-cookbook/), see [List changed files between two commits](https://github.com/centic9/jgit-cookbook/blob/master/src/main/java/org/dstadler/jgit/porcelain/DiffFilesInCommit.java) [List changed files in index](https://github.com/centic9/jgit-cookbook/blob/master/src/main/java/org/dstadler/jgit/porcelain/DiffIndexChanges.java) [List changed files in checkout](https://github.com/centic9/jgit-cookbook/blob/master/src/main/java/org/dstadler/jgit/porcelain/DiffLocalChanges.java) – centic Aug 04 '23 at 07:53
0
    Git git = Git.open(new File("xxx"));
    Repository repository = git.getRepository();
    DiffFormatter diffFormatter = new DiffFormatter(System.out);
    diffFormatter.setRepository(repository);

    ObjectReader reader = git.getRepository().newObjectReader();
    CanonicalTreeParser oldTreeIter = new CanonicalTreeParser();
    ObjectId headTree = git.getRepository().resolve( "HEAD^{tree}" );
    oldTreeIter.reset( reader, headTree );
    AbstractTreeIterator newTreeIter = new FileTreeIterator(git.getRepository());
    diffFormatter.format(oldTreeIter, newTreeIter);
chineseboy
  • 13
  • 3
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Aug 08 '23 at 14:09