git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [JGIT] Blame functionality for jgit

From
MWManuel Woelker <manuel.woelker@gmail.com>
Date
Jan 12, 2009, 21:17 UTC
Message-ID
<3d045c7e0901121317j4ccd9515vbc7a44abc8ae5356@mail.gmail.com>
In-Reply-To
<20090112174232.GJ10179@spearce.org>
On Mon, Jan 12, 2009 at 6:42 PM, Shawn O. Pearce <spearce@spearce.org> wrote:
Show 8 quoted lines
>
>> I largely ported the cgit blame algorithm described here
>> https://kerneltrap.org/mailarchive/git/2006/10/12/224187 , the
>> relevant file is builtin-blame.c cf.
>> http://repo.or.cz/w/git.git?a=blob;f=builtin-blame.c;hb=HEAD
>
> OK.  Fortunately Junio has largely given his blessing to this code
> being converted to Java under the BSD license.

Glad to hear that, Dscho already mentioned that a port like this might raise license concerns. So I hope Junio would be okay with that.

Show 16 quoted lines
> Unfortunately I can't reach incava.org to download java-diff, but
> its entry on sourceforge says it uses an LGPL license.  Within JGit
> we do want to stick to BSD and BSD dependencies, so bringing in
> java-diff as a new dependency isn't something we really want to do.
>
> Fortunately Dscho has been working on a Java diff implementation for
> JGit, and is considering releasing it under a BSD license so we can
> include it.
>
> The interface is still to be decided, but in general we have
> found that running against a byte[] is much faster than running
> against String.  We're probably going to want the diff library to
> take a byte[] and an IntList (as created by RawParseUtils.lineMap)
> and let it work against the byte array ranges directly, without any
> additional allocations, except where it needs to build up its hash
> of records.

That sounds like a good plan. For now I am not all that concerned about performance myself (premature optimization and all that), but in the long run - and especially with rename/copy detection that will definitely a factor for usability. We could adopt the interface to allow for a "fast" implementation, and have existing diff implementations adapted to that. I'd be very interested to see Dscho's diff work, and maybe we can get something going on that front. A patience diff implementation would be rather neat too, and all my googling hasn't turned up anything.

Show 5 quoted lines
> I think eventually we'll have a BSD licensed LCS that will come with
> JGit, which would eliminate the need for such a shim.  I'd like
> to see that happen before blame gets added, but if blame is ready
> and the shim is reasonably well done, I'm inclined to bring blame
> in early.

While trying to look up the Myers diff algorithm I found a diff implementation in Apache wicket (cf. http://wicket.sourceforge.net/apidocs/wicket/util/diff/myers/package-summary.html ). This one is under an Apache license, is that any better? It's truly kind of sad that you need a degree in law these days to get any work done in this license jungle. I just happen to strongly oppose the reinvention of circular transportation-enabling devices...

Show 48 quoted lines
> - Don't use @author tags, we don't use them anywhere else.
>
> - Please include copyright headers on all new files.
>
> - I think the IDiff, IDifference should be in a ".diff" package so
> we can reuse them for other diff applications.  Especially if we
> wind up using a shim to link to different LCS implementations.
>
> - I think the API for BlameEngine should be more like:
>
>  public class BlameEngine {
>    private final RevWalk rw;
>
>    public BlameEngine(final Repository repo) {
>      this(new RevWalk(repo));
>    }
>
>    public BlameEngine(final RevWalk walk) {
>      rw = walk;
>    }
>
>    public RevWalk getRevWalk() {
>      return rw;
>    }
>
>    public List<BlameEntry> blame(RevCommit c, String path);
>  }
>
>  One reason for this style of API is we can have the engine cache
>  blame records.  This can make a GUI navigator much more efficient
>  as it jumps around between commits and asks for blames over the
>  same data.
>
> - Internally you should *always* use RevCommit, not Commit.
> The RevCommit class can be orders of magnitude faster than Commit.
>
> - Internally you should always use RevTree and TreeWalk to locate
> blob IDs.  Its orders of magnitude faster than Tree and TreeEntry.
>
> - Don't use new String(loader.getBytes()) (e.g. in Origin.getData)
> to get the data for a file.  We want to do raw diffs, so that the
> character encoding is considered as part of the blame.  E.g. if
> a file switches character encodings, the blame has to go to the
> commit that introduced the new encoding.  This is a huge reason
> to use byte[] and IntList over an array of String.
>
> - RawParseUtils.lineMap will be faster than a Pattern of "^(.*)$".
>

Thanks for the comments. This first version was basically just a proof-of-concept to see if and how it could work. I didn't want to pour too much effort into, before knowing if this project was viable at all. This input is very valuable and I will try to incorporate the suggestions into future revisions.

I'll keep you posted on new developments
 - Manuel
Previous: Shawn O. PearceNext: Shawn O. Pearce
Message 3 of 4 in “[JGIT] Blame functionality for jgit”
  1. Manuel WoelkerJan 11, 2009
  2. Shawn O. PearceJan 12, 2009
  3. Manuel WoelkerJan 12, 2009
  4. Shawn O. PearceJan 12, 2009

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.