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

Re: [Feature Request] git blame showing only revisions from git rev-list --first-parent

From
Jeff King <peff@peff.net>
Date
Sep 12, 2015, 03:30 UTC
Message-ID
<20150912033054.GA30431@sigill.intra.peff.net>
In-Reply-To
<xmqqsi6kzsgc.fsf@gitster.mtv.corp.google.com>
On Fri, Sep 11, 2015 at 12:06:27PM -0700, Junio C Hamano wrote:
Show 6 quoted lines
> So here is an outline of what I had in mind when I was writing the
> above.  Instead of trusting that num_scapegoats() is always used to
> limit the enumeration of commit->parents, we discard the second and
> subsequent parents from the commit objects, and also make sure the
> later parents do not participate in the revs.children annotation, so
> that the world "blame" sees truly becomes a single strand of pearls.
Yeah, I think what is happening in this first hunk:
Show 20 quoted lines
> diff --git a/builtin/blame.c b/builtin/blame.c
> index 4db01c1..bc87d9d 100644
> --- a/builtin/blame.c
> +++ b/builtin/blame.c
> @@ -1366,8 +1366,15 @@ static void pass_whole_blame(struct scoreboard *sb,
>   */
>  static struct commit_list *first_scapegoat(struct rev_info *revs, struct commit *commit)
>  {
> -	if (!reverse)
> +	if (!reverse) {
> +		if (revs->first_parent_only &&
> +		    commit->parents &&
> +		    commit->parents->next) {
> +			free_commit_list(commit->parents->next);
> +			commit->parents->next = NULL;
> +		}
>  		return commit->parents;
> +	}
>  	return lookup_decoration(&revs->children, &commit->object);
>  }

is doing the right thing. It did feel a little weird to me to be munging the global commit objects themselves, but I guess it is fairly normal for git code.

I wondered if you could then simplify away the counters used in the for-loops. I.e., to end up with:

  for (sg = first_scapegoat(revs, commit); sg; sg = sg->next)

in the callers. But no. One of the reasons for the counters is that we need to know we are on the n'th parent, so we can compare it to parent n-1, n-2, etc, for sameness.

Show 15 quoted lines
> diff --git a/revision.c b/revision.c
> index af2a18e..a020a42 100644
> --- a/revision.c
> +++ b/revision.c
> @@ -2765,7 +2765,9 @@ static void set_children(struct rev_info *revs)
>  		struct commit *commit = l->item;
>  		struct commit_list *p;
>  
> -		for (p = commit->parents; p; p = p->next)
> +		for (p = commit->parents;
> +		     p && !revs->first_parent_only;
> +		     p = p->next)
>  			add_child(revs, p->item, commit);
>  	}
>  }

Yeah, this makes sense to me. Adding all children to the decoration list and then later choosing only the first child (as my earlier suggestion did) is not right. You can tell immediately that it is nonsense because the child you would get depends on the order we visited the commits when building up the decoration. And that does not necessarily have any real meaning.

-Peff
Previous: Junio C HamanoNext: Junio C Hamano
Message 6 of 16 in “[Feature Request] git blame showing only revisions from git rev-list --first-parent”
  1. Stephen ConnollySep 11, 2015
  2. Jeff KingSep 11, 2015
  3. Stephen ConnollySep 11, 2015
  4. Junio C HamanoSep 11, 2015
  5. Junio C HamanoSep 11, 2015
  6. Jeff KingSep 12, 2015
  7. Junio C HamanoSep 12, 2015
  8. Philip OakleySep 12, 2015
  9. Jeff KingSep 13, 2015
  10. Junio C HamanoSep 14, 2015
  11. Jeff KingSep 15, 2015
  12. Junio C HamanoSep 16, 2015
  13. Jeff KingSep 16, 2015
  14. Junio C HamanoSep 17, 2015
  15. Max KirillovOct 18, 2015
  16. Junio C HamanoOct 18, 2015

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.