blame: Compute the origin of lines in a result file

BlameGenerator digs through history and discovers the origin of each
line of some result file.  BlameResult consumes the stream of regions
created by the generator and lays them out in a table for applications
to display alongside of source lines.

Applications may optionally push in the working tree copy of a file
using the push(String, byte[]) method, allowing the application to
receive accurate line annotations for the working tree version.  Lines
that are uncommitted (difference between HEAD and working tree) will
show up with the description given by the application as the author,
or "Not Committed Yet" as a default string.

Applications may also run the BlameGenerator in reverse mode using the
reverse(AnyObjectId, AnyObjectId) method instead of push().  When
running in the reverse mode the generator annotates lines by the
commit they are removed in, rather than the commit they were added in.
This allows a user to discover where a line disappeared from when they
are looking at an older revision in the repository.  For example:

  blame --reverse 16e810b2..master -L 1080, org.eclipse.jgit.test/tst/org/eclipse/jgit/storage/file/RefDirectoryTest.java
           (                                              1080)   }
  2302a6d3 (Christian Halstrick 2011-05-20 11:18:20 +0200 1081)
  2302a6d3 (Christian Halstrick 2011-05-20 11:18:20 +0200 1082)   /**
  2302a6d3 (Christian Halstrick 2011-05-20 11:18:20 +0200 1083)    * Kick the timestamp of a local file.

Above we learn that line 1080 (a closing curly brace of the prior
method) still exists in branch master, but the Javadoc comment below
it has been removed by Christian Halstrick on May 20th as part of
commit 2302a6d3.  This result differs considerably from that of C
Git's blame --reverse feature.  JGit tells the reader which commit
performed the delete, while C Git tells the reader the last commit
that still contained the line, leaving it an exercise to the reader
to discover the descendant that performed the removal.

This is still only a basic implementation.  Quite notably it is
missing support for the smart block copy/move detection that the C
implementation of `git blame` is well known for.  Despite being
incremental, the BlameGenerator can only be run once.  After the
generator runs it cannot be reused.  A better implementation would
support applications browsing through history efficiently.

In regards to CQ 5110, only a little of the original code survives.

CQ: 5110
Bug: 306161
Change-Id: I84b8ea4838bb7d25f4fcdd540547884704661b8f
Signed-off-by: Kevin Sawicki <kevin@github.com>
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>
13 files changed