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

Re: [PATCH v6 0/6] blame: add the ability to ignore commits

From
BRBarret Rhoden <brho@google.com>
Date
Apr 23, 2019, 18:13 UTC
Message-ID
<533f7721-2af6-1137-17c1-065837e1321d@google.com>
In-Reply-To
<20190422222647.48628-1-michael@platin.gs>
Hi Michael -
On 4/22/19 6:26 PM, michael@platin.gs wrote:
Show 8 quoted lines
> +	int *matching_lines = fuzzy_find_matching_lines(parent->file.ptr,
> +							target->file.ptr,
> +							parent->line_starts,
> +							target->line_starts,
> +							e->s_lno + offset,
> +							e->s_lno,
> +							parent_len,
> +							e->num_lines);

Here was the issue I ran into, and it's due to translations between e->s_lno and the parent's "address space".

The short version is that "e->s_lno + offset" is not always the parent_slno, and parent_len is based off of parent_slno.

guess_line_blames() gives you parent_slno and parent_len, as well as offset. 'offset' is how you convert from the target's space to the parent's. parent_slno and parent_len describe the whole chunk given to us from the diff engine. However, there may be multiple blame_entries covering that chunk.

So e->s_lno is in the target, but it's not necessarily the beginning of the entire diff chunk. This is related to that page fault you found a while back.

Passing e->s_lno + offset for where fuzzy() starts looking in the parent is fine, but then the length in the parent needs to be adjusted. For instance, I have this at the top of my modified fuzzy_find_matching_lines() (changed to take the origins and variables from guess_line_blames()):

         // XXX conversions to michael's variable names
	int start_a = e->s_lno + offset;
         //int length_a = parent_len;    // XXX this fails the test
         int length_a = (parent_slno + parent_len) - (e->s_lno + offset);
	int start_b = e->s_lno;
         int length_b = e->num_lines;

Plus we need a check for length_a <= 0. I had to work to make it be negative, but it's possible. parent_slno = tlno + offset, so we're looking at:

	length_a = tlno + parent_len - e->s_lno;

That just requires a blame entry split such that e->s_lno > tlno, and a parent chunk that had 0 lines. I found a case that did that. Basically in one commit you add a bunch of lines. In another, you change one line in the middle of that bunch. That causes a split of the diff chunk into more than one, such that e->s_lno > tlno. That original commit only added lines, so parent_len == 0.

The intuition for the "negative length_a" isn't that the parent_len is negative, it's that the e->s_lno chunk (when offset) is outside the window of the parent's change. I have a simple test for this.

Oh, and we have to length_a == 0, due to this:
	max_search_distance = length_a - 1;

Anyway, I'll take what I've got and apply your latest and see what I come up with. =) Plus, I have fixes for all of the other stuff brought up in the v6 discussion.

Barret
Previous: Barret RhodenNext: Barret Rhoden
Message 3 of 6 in “RE: [PATCH v6 0/6] blame: add the ability to ignore commits”
  1. michael@platin.gsApr 22, 2019
  2. Barret RhodenApr 23, 2019
  3. Barret RhodenApr 23, 2019
  4. Barret RhodenApr 23, 2019
  5. Barret RhodenApr 23, 2019
  6. Barret RhodenApr 24, 2019

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.