Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting commit information from a RevCommit object in JGit

Tags:

git

jgit

I called the jgit log command and got back some RevCommit objects. I can get back some basic information from it and I use the following code to get the list of files that changed. There are two more things that I need though:

1) how do I get the information below when the commit doesn't have a parent?

2) how do I get the diff of the content that changed in each file

RevCommit commit = null;

RevWalk rw = new RevWalk(repository);

RevCommit parent = null;
if (commit.getParent(0) != null) {
   parent = rw.parseCommit(commit.getParent(0).getId());
}

DiffFormatter df = new DiffFormatter(DisabledOutputStream.INSTANCE);
df.setRepository(repository);
df.setDiffComparator(RawTextComparator.DEFAULT);
df.setDetectRenames(true);

List<DiffEntry> diffs = df.scan(parent.getTree(), commit.getTree());
for (DiffEntry diff : diffs) {
   System.out.println(getCommitMessage());

   System.out.println("changeType=" + diff.getChangeType().name()
           + " newMode=" + diff.getNewMode().getBits()
           + " newPath=" + diff.getNewPath()
           + " id=" + getHash());
}
like image 636
Coder Avatar asked Sep 19 '12 11:09

Coder


1 Answers

1) Use the overloaded scan method with AbstractTreeIterator and call it as follows in case of no parent:

df.scan(new EmptyTreeIterator(),
        new CanonicalTreeParser(null, rw.getObjectReader(), commit.getTree());

The case of no parent is only for the initial commit, in which case the "before" of the diff is empty.

2) If you want git diff style output, use the following:

df.format(diff);

And the diff will be written to the output stream passed to the constructor. So to get each diff individually, it should be possible to use one DiffFormatter instance per file. Or you could use one DiffFormatter with a ByteArrayOutputStream, get the contents and reset it before formatting the next file. Roughly like this:

ByteArrayOutputStream out = new ByteArrayOutputStream();
DiffFormatter df = new DiffFormatter(out);
// ...
for (DiffEntry diff : diffs) {
    df.format(diff);
    String diffText = out.toString("UTF-8");
    // use diffText
    out.reset();
}

Note that Git does not know the encoding of files, this has to be specified in the toString() method. Here it uses a reasonable default. Depending on your use case you may be better off not decoding it by using toByteArray().


A general note: Ensure that you always release the resources of RevWalk and DiffFormat using release().

like image 59
robinst Avatar answered Oct 31 '22 12:10

robinst