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

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

From
Marc Branchaud <marcnarc@xiplink.com>
Date
May 14, 2025, 21:15 UTC
Message-ID
<6b034b50-4661-4887-8a6e-86bc42c3a935@xiplink.com>
In-Reply-To
<874ixnjltf.fsf@iotcl.com>

(I agree with Junio's reply to your message, so here I'm just going to address the things that Junio didn't.)

I'll preface all this by restating my original point: If you really want to implement this feature as a new command, please don't use "blame" in that new command's name.

On 2025-05-14 10:42, Toon Claes wrote:
Show 15 quoted lines
> 
> 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.
The behavior is not ambiguous at all, it's simply context-dependent.

Like with "git add": We don't have "git add-tree" to add a directory of files. Adding is adding, and so we make the "add" command handle all types of adding.

Similarly, we don't need "blame-tree" to annotate a directory. Just because annotating a single file has different output from annotating a tree of files doesn't mean that we need two different verbs to annotate either kind of object.

Show 5 quoted lines
>> 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`?

If a user wants to blame/annotate something -- a tree or a file -- it's much easier for them to just use one command to blame whatever they want. No need to discover a different command and read a whole new man page to figure it out.

And all the people who already know about "git blame" get new and useful behavior from their familiar command. They are much more likely to discover that when it's built into "git blame" than if the new feature is hiding under a different command.

Also, people who tab-complete commands will appreciate that
	git bl<tab>
continues to complete to "git blame " instead of "git blame".  (You 
could argue that this is one way people might discover blame-tree, but I 
think messing with completionists' muscle-memory is going to annoy them 
more than help them.)
Show 7 quoted lines
>> 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.

Extending an existing command is an incremental way of making things better for all the people who are already using that command. They are more likely to discover the new behavior, either by spotting it when they're checking the man page or, in this case, by accidentally passing a directory to "git blame".

Hiding this in a new command makes it much less likely to be discovered by current Git users.

Yes, it is an advertising issue. I don't consider Git to be a gold standard for feature discoverability. So I don't think that simply saying it's more of an advertising problem gets us anywhere, because so far Git has failed miserably at advertising its commands.

Show 13 quoted lines
>> 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.

I don't buy that. Many Unix commands give different outputs when run against a file vs. a directory (try diff, for example). Even simple things like "ls" will show a single line of output for a file but multiple lines for a directory. You can argue that one line vs. many isn't a drastic difference, but it *is* a difference. And there's a reason why it's "ls -R" instead of "ls-tree": Listing is listing, so "ls" fulfills all your listing needs.

> The format of the output returned will be drastically different in both
> cases, and having to machine-parse this might be tricky.
Machine-parsing output is a strawman.

First of all, even though "blame" is considered an ancillary command and not officially listed as porcelain, it's also not plumbing and so it has no obligation to make machines' lives easier.

Second, why do you think a script needs to parse both output formats? 
Even if there are reasons to write such a script, how does having two 
commands for the different formats help?  Either way such a script's 
author needs to deal with both formats.  Furthermore, if I was 
maintaining a script that already understands how to parse single-file 
annotation:
	git blame path/to/file | my-script
I would be quite happy for it to die horribly if someone ran it on the 
output of a tree annotation.

As you say, in that pipe example teaching my-script how to tell what kind of output it's receiving could be tricky. But I doubt that many existing scripts that parse blame output are implemented as pipe-readers. Rather, I think (yes, without any evidence) that most script authors run the blame command directly as part of their script and so they'll know what kind of output the command they're running will generate (since they'll know what kind of arguments they're passing to the commmand).

Folks who really need to write a pipe-reader can just teach their script an argument identifying the kind of output to expect. Much easier, and more robust, than making the code figure it out. Pipe-reading scripts will need figure out something like this regardless of how we resolve this discussion.

		M.
Previous: Patrick SteinhardtNext: Kristoffer Haugsbakk
Message 27 of 135 in “Introduce git-blame-tree(1) command”
  1. 0/5 Introduce git-blame-tree(1) commandToon Claes, Apr 22, 2025
  2. 1/5 blame-tree: introduce new subcommand to blame filesToon Claes, Apr 22, 2025
  3. Junio C HamanoApr 24, 2025
  4. Toon ClaesMay 7, 2025
  5. 2/5 t/perf: add blame-tree perf scriptToon Claes, Apr 22, 2025
  6. 3/5 blame-tree: use Bloom filters when availableToon Claes, Apr 22, 2025
  7. 4/5 blame-tree: implement faster algorithmToon Claes, Apr 22, 2025
  8. 5/5 blame-tree.c: initialize revision machinery without walkToon Claes, Apr 22, 2025
  9. Marc BranchaudApr 23, 2025
  10. Toon ClaesMay 7, 2025
  11. Marc BranchaudMay 7, 2025
  12. Junio C HamanoMay 7, 2025
  13. Marc BranchaudMay 8, 2025
  14. Junio C HamanoMay 8, 2025
  15. Marc BranchaudMay 8, 2025
  16. Toon ClaesMay 14, 2025
  17. Junio C HamanoMay 14, 2025
  18. Marc BranchaudMay 14, 2025
  19. Patrick SteinhardtMay 15, 2025
  20. Junio C HamanoMay 15, 2025
  21. Marc BranchaudMay 15, 2025
  22. Jeff KingMay 15, 2025
  23. Patrick SteinhardtMay 16, 2025
  24. Toon ClaesMay 20, 2025
  25. Marc BranchaudMay 15, 2025
  26. Patrick SteinhardtMay 16, 2025
  27. Marc BranchaudMay 14, 2025
  28. Kristoffer HaugsbakkMay 7, 2025
  29. D. Ben KnobleMay 8, 2025
  30. Marc BranchaudMay 8, 2025
  31. D. Ben KnobleMay 8, 2025
  32. 0/5 Introduce git-last-modified(1) commandToon Claes, May 23, 2025
  33. 1/5 last-modified: new subcommand to show when files were last modifiedToon Claes, May 23, 2025
  34. Justin ToblerMay 25, 2025
  35. Toon ClaesJun 5, 2025
  36. Patrick SteinhardtMay 27, 2025
  37. Toon ClaesJun 13, 2025
  38. Kristoffer HaugsbakkJun 13, 2025
  39. 2/5 t/perf: add last-modified perf scriptToon Claes, May 23, 2025
  40. 3/5 last-modified: use Bloom filters when availableToon Claes, May 23, 2025
  41. Patrick SteinhardtMay 27, 2025
  42. Toon ClaesJun 13, 2025
  43. 4/5 last-modified: implement faster algorithmToon Claes, May 23, 2025
  44. Patrick SteinhardtMay 27, 2025
  45. 5/5 last-modified: initialize revision machinery without walkToon Claes, May 23, 2025
  46. Patrick SteinhardtMay 27, 2025
  47. Kristoffer HaugsbakkJul 1, 2025
  48. Junio C HamanoJul 1, 2025
  49. Kristoffer HaugsbakkJul 1, 2025
  50. Toon ClaesJul 2, 2025
  51. Toon ClaesJul 9, 2025
  52. Junio C HamanoJul 9, 2025
  53. 0/3 Introduce git-last-modified(1) commandToon Claes, Jun 30, 2025
  54. 1/3 last-modified: new subcommand to show when files were last modifiedToon Claes, Jun 30, 2025
  55. Kristoffer HaugsbakkJul 1, 2025
  56. Junio C HamanoJul 2, 2025
  57. 2/3 t/perf: add last-modified perf scriptToon Claes, Jun 30, 2025
  58. 3/3 last-modified: use Bloom filters when availableToon Claes, Jun 30, 2025
  59. Junio C HamanoJul 1, 2025
  60. 0/3 Introduce git-last-modified(1) commandToon Claes, Jul 9, 2025
  61. Junio C HamanoJul 9, 2025
  62. Junio C HamanoJul 10, 2025
  63. 0/6 Introduce git-last-modified(1) commandToon Claes, Jul 16, 2025
  64. 1/6 last-modified: new subcommand to show when files were last modifiedToon Claes, Jul 16, 2025
  65. Taylor BlauJul 18, 2025
  66. Jeff KingJul 19, 2025
  67. Toon ClaesJul 22, 2025
  68. Christian CouderAug 1, 2025
  69. Junio C HamanoAug 1, 2025
  70. 2/6 t/perf: add last-modified perf scriptToon Claes, Jul 16, 2025
  71. Taylor BlauJul 18, 2025
  72. Toon ClaesJul 22, 2025
  73. 3/6 last-modified: use Bloom filters when availableToon Claes, Jul 16, 2025
  74. Taylor BlauJul 18, 2025
  75. Toon ClaesJul 22, 2025
  76. 4/6 pretty: allow caller to disable indentationToon Claes, Jul 16, 2025
  77. Junio C HamanoJul 16, 2025
  78. Toon ClaesJul 17, 2025
  79. 5/6 last-modified: support --extended formatToon Claes, Jul 16, 2025
  80. Junio C HamanoJul 16, 2025
  81. Toon ClaesJul 17, 2025
  82. Junio C HamanoJul 17, 2025
  83. Junio C HamanoJul 18, 2025
  84. Toon ClaesJul 22, 2025
  85. 6/6 fixup! last-modified: use Bloom filters when availableToon Claes, Jul 16, 2025
  86. Taylor BlauJul 17, 2025
  87. Toon ClaesJul 22, 2025
  88. Toon ClaesJul 30, 2025
  89. Patrick SteinhardtJul 31, 2025
  90. 0/4 Introduce git-last-modified(1) commandToon Claes, Jul 30, 2025
  91. Junio C HamanoJul 31, 2025
  92. Junio C HamanoJul 31, 2025
  93. 0/3 Introduce git-last-modified(1) commandToon Claes, Aug 5, 2025
  94. Patrick SteinhardtAug 5, 2025
  95. Junio C HamanoAug 5, 2025
  96. Junio C HamanoAug 5, 2025
  97. Toon ClaesAug 5, 2025
  98. Jean-Noël AVILAAug 5, 2025
  99. Junio C HamanoAug 5, 2025
  100. Toon ClaesAug 6, 2025
  101. Junio C HamanoAug 6, 2025
  102. Junio C HamanoAug 28, 2025
  103. Junio C HamanoAug 5, 2025
  104. 1/3 last-modified: new subcommand to show when files were last modifiedToon Claes, Aug 5, 2025
  105. 2/3 t/perf: add last-modified perf scriptToon Claes, Aug 5, 2025
  106. 3/3 last-modified: use Bloom filters when availableToon Claes, Aug 5, 2025
  107. 1/4 last-modified: new subcommand to show when files were last modifiedToon Claes, Jul 30, 2025
  108. Patrick SteinhardtJul 31, 2025
  109. Toon ClaesAug 1, 2025
  110. Junio C HamanoAug 1, 2025
  111. Patrick SteinhardtAug 4, 2025
  112. Junio C HamanoAug 4, 2025
  113. Toon ClaesAug 5, 2025
  114. Jean-Noël AVILAAug 1, 2025
  115. Toon ClaesAug 5, 2025
  116. Patrick SteinhardtAug 4, 2025
  117. Christian CouderAug 1, 2025
  118. Patrick SteinhardtAug 1, 2025
  119. Junio C HamanoAug 1, 2025
  120. Christian CouderAug 2, 2025
  121. Christian CouderAug 2, 2025
  122. Christian CouderAug 2, 2025
  123. Junio C HamanoAug 2, 2025
  124. Patrick SteinhardtAug 4, 2025
  125. 2/4 t/perf: add last-modified perf scriptToon Claes, Jul 30, 2025
  126. 3/4 commit-graph: export prepare_commit_graph()Toon Claes, Jul 30, 2025
  127. Patrick SteinhardtJul 31, 2025
  128. 4/4 last-modified: use Bloom filters when availableToon Claes, Jul 30, 2025
  129. Patrick SteinhardtJul 31, 2025
  130. Toon ClaesAug 1, 2025
  131. Patrick SteinhardtAug 4, 2025
  132. 1/3 last-modified: new subcommand to show when files were last modifiedToon Claes, Jul 9, 2025
  133. 2/3 t/perf: add last-modified perf scriptToon Claes, Jul 9, 2025
  134. 3/3 last-modified: use Bloom filters when availableToon Claes, Jul 9, 2025
  135. 6/6 fixup! last-modified: use Bloom filters when availableToon Claes, Jul 16, 2025

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.