Search code examples
javajgit

How to use JGit to view modifications in the local workspace?


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.


Solution

  • 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/