Subject: Re: [PATCH RFC 0/5] Introduce git-blame-tree(1) command

From: Toon Claes <[email-masked]>
Date: Wed, 14 May 2025 16:42:20 +0200

Marc Branchaud <[email-masked]> writes:

> On 2025-05-08 10:26, Junio C Hamano wrote:
>> Marc Branchaud <[email-masked]> writes:
>> 
>>> This distinction brings up a wrinkle in my proposed DWIMery: should
>>> 	git blame path/to/file
>>> show the annotated blamed lines of the file, or simply display the
>>> last commit that changed the file?
>> 
>> I thought you switch to blame-at-the-file-level only when you are
>> given a directory (or a tree)?  "git blame path/to/file" has ALWAYS
>> done "blame these lines that appear in this file", and cannot change.

I don't know about that. What if you want to blame multiple files:

  $ git blame-tree refs.c refs.h

or (letting your shell do the globbing):

  $ $ git blame-tree *.h

I see these use-cases are very convenient. At GitLab we need to have
some kind pagination on files in a tree, if we can pass individual
filenames, we could use that for pagination.

>> Of course you can say "git blame path/to/ | grep file"; as you said
>> yourself,

This isn't very efficient. If a file in that tree was only touched in
the "initial commit" you have to wait for the blame process to walk the
history all the way down to that commit, while you're not actually
interested in that file.

>> 
>>> 	git log -1 path/to/file
>> 
>> is so obvious, we do not need to introduce yet another way to get to
>> the same information, I think.

Well, if you can pass multiple files (which git-blame-tree(1) currently
can) it's way more efficient to walk the history once, and see along the
history which file was touched when. For us at GitLab that's the whole
idea of upstreaming this feature.

> Fine by me.  I personally don't think of "git blame" when I want to see 
> a file's commit history.

Personally I don't like the idea of the DWIM approach. I rather keep
following the UNIX philosophy and having each command do one thing well.
I think it weird to change behavior based on context.

You said earlier in this thread:

> This distinction brings up a wrinkle in my proposed DWIMery: should
>         git blame path/to/file
> show the annotated blamed lines of the file, or simply display the last 
> commit that changed the file?

For me this gives good motivation to not mix behavior of file-level and
line-level blames into a single command. If behavior in ambiguous, we
should avoid it.

> I can appreciate the convenience of being able to do that with "git 
> blame".  I suggest adding an option for this specific case, like maybe 
> "--latest" (I don't feel strongly about the option's name).

What makes `git blame --latest` better than `git blame-tree`?

> I agree that blaming is a well-(known) concept.  I also agree that most 
> users would understand what blame-tree would do, *once they find it*.

I'm also not convinced why a option argument to an existing command
would be easier to discover than a new command. I think it's more an
issue of us advertising features, than commands being discoverable on
it's own.

> Also, I think sacrificing usability because it makes the coding hard is 
> unfortunate.

Agreed, that was not a good motivation from my side to make.

I wrote:
> > Forgive me, but I think folding into git-blame(1) will also solidify
> > Git's reputation of obscurity.
> 
> Please elaborate.

As I mentioned above, I think having behavior of git-blame(1) depend on
the type of the argument (is it a dir or a file) is rather obscure. The
format of the output returned will be drastically different in both
cases, and having to machine-parse this might be tricky.

Cheers,
-- Toon