Skip to content

line-log: integrate -L with the standard log output pipeline#2094

Open
mmontalbo wants to merge 3 commits into
gitgitgadget:masterfrom
mmontalbo:mm/line-log-use-log-tree-diff-flush
Open

line-log: integrate -L with the standard log output pipeline#2094
mmontalbo wants to merge 3 commits into
gitgitgadget:masterfrom
mmontalbo:mm/line-log-use-log-tree-diff-flush

Conversation

@mmontalbo
Copy link
Copy Markdown

@mmontalbo mmontalbo commented Apr 19, 2026

Since its introduction, git log -L has short-circuited from
log_tree_commit() into its own output function, bypassing
log_tree_diff() and log_tree_diff_flush(). This skips no_free
save/restore, always_show_header, diff_free() cleanup, and
means that pickaxe (-S, -G, --find-object) and --diff-filter
cannot suppress commits whose pairs are all filtered out, because
show_log() runs before diffcore_std().

This series restructures the flow so that -L goes through the
same log_tree_diff() -> log_tree_diff_flush() path as normal
single-parent and merge diffs, then uses that to enable several
non-patch diff formats.

Patch 1: revision: move -L setup before output_format-to-diff derivation

Preparatory reorder in setup_revisions(). The -L block sets a
default DIFF_FORMAT_PATCH when no format is requested; move it
before the derivation of revs->diff from output_format so the
default is visible to that check. No behavior change on its own.

Patch 2: line-log: integrate -L output with the standard log-tree pipeline

Rename line_log_print() to line_log_queue_pairs(), stripping it
down to only queue pre-computed filepairs. log_tree_diff_flush()
handles show_log(), diffcore_std(), and diff_flush(). This
fixes pickaxe and --diff-filter suppression, and aligns the
commit/diff separator with the rest of log output. Also rejects
--full-diff, which is meaningless when filepairs are pre-computed.

Patch 3: line-log: allow non-patch diff formats with -L

Expand the allowlist to accept --raw, --name-only,
--name-status, and --summary. These only read filepair metadata
already set by the line-log machinery. Diff stat formats (--stat,
--numstat, --shortstat, --dirstat) remain blocked because they
call compute_diffstat() on full blob content and would show
whole-file statistics rather than range-scoped ones.

cc: "D. Ben Knoble" ben.knoble@gmail.com

@mmontalbo mmontalbo force-pushed the mm/line-log-use-log-tree-diff-flush branch from b1082fe to 151ccc5 Compare April 27, 2026 21:42
The line_level_traverse block sets a default DIFF_FORMAT_PATCH when
no output format has been explicitly requested.  This default must
be visible to the "Did the user ask for any diff output?" check
that derives revs->diff from revs->diffopt.output_format.

Currently the -L block runs after that derivation, so revs->diff
stays 0 when no explicit format is given.  This does not matter yet
because log_tree_commit() short-circuits into line_log_print()
before consulting revs->diff, but the next commit will route -L
through the normal log_tree_diff() path, which checks revs->diff.

Move the block above the derivation so the default DIFF_FORMAT_PATCH
is in place when revs->diff is computed.  No behavior change on its
own.

Signed-off-by: Michael Montalbo <mmontalbo@gmail.com>
`git log -L` has bypassed log_tree_diff() and log_tree_diff_flush()
since the feature was introduced, short-circuiting from
log_tree_commit() directly into line_log_print().  This skips the
no_free save/restore (noted in a NEEDSWORK comment added by
f8781bf), the always_show_header fallback, show_diff_of_diff(),
and diff_free() cleanup.

Restructure so that -L flows through log_tree_diff() ->
log_tree_diff_flush(), the same path used by the normal
single-parent and merge diff codepaths:

 - Rename line_log_print() to line_log_queue_pairs() and strip it
   down to just queuing pre-computed filepairs.  The show_log(),
   separator, diffcore_std(), and diff_flush() calls are removed
   since log_tree_diff_flush() handles all of those.

 - In log_tree_diff(), call line_log_queue_pairs() then
   log_tree_diff_flush(), mirroring the diff_tree_oid() + flush
   pattern used by the single-parent and merge codepaths.

 - Remove the early return in log_tree_commit() that bypassed
   no_free save/restore, always_show_header, and diff_free().

Because show_log() is now deferred until after diffcore_std() inside
log_tree_diff_flush(), pickaxe (-S, -G, --find-object) and
--diff-filter now properly suppress commits when all pairs are
filtered out.

The blank-line separator between commit header and diff changes
slightly: the old code printed one unconditionally, while
log_tree_diff_flush() only emits one for verbose headers.  This
matches the rest of log output.

Also reject --full-diff, which is meaningless with -L: the filepairs
are pre-computed during the history walk and scoped to tracked paths,
so there is no tree diff to widen.

Update tests accordingly.

Signed-off-by: Michael Montalbo <mmontalbo@gmail.com>
@mmontalbo mmontalbo force-pushed the mm/line-log-use-log-tree-diff-flush branch from 151ccc5 to 1c88248 Compare April 27, 2026 22:14
Now that -L flows through log_tree_diff_flush() and diff_flush(),
metadata-only diff formats work because they only read filepair
fields (status, mode, path, oid) already set on the pre-computed
pairs.

Expand the allowlist in setup_revisions() to also accept --raw,
--name-only, --name-status, and --summary.  Diff stat formats
(--stat, --numstat, --shortstat, --dirstat) remain blocked because
they call compute_diffstat() on full blob content and would show
whole-file statistics rather than range-scoped ones.

Signed-off-by: Michael Montalbo <mmontalbo@gmail.com>
@mmontalbo mmontalbo force-pushed the mm/line-log-use-log-tree-diff-flush branch from 1c88248 to 06c24b4 Compare April 27, 2026 22:44
@mmontalbo
Copy link
Copy Markdown
Author

/preview

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented Apr 28, 2026

Preview email sent as pull.2094.git.1777348749.gitgitgadget@gmail.com

@mmontalbo
Copy link
Copy Markdown
Author

/submit

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented Apr 28, 2026

Submitted as pull.2094.git.1777349126.gitgitgadget@gmail.com

To fetch this version into FETCH_HEAD:

git fetch https://github.com/gitgitgadget/git/ pr-2094/mmontalbo/mm/line-log-use-log-tree-diff-flush-v1

To fetch this version to local tag pr-2094/mmontalbo/mm/line-log-use-log-tree-diff-flush-v1:

git fetch --no-tags https://github.com/gitgitgadget/git/ tag pr-2094/mmontalbo/mm/line-log-use-log-tree-diff-flush-v1

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented May 3, 2026

This branch is now known as mm/line-log-cleanup.

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented May 3, 2026

This patch series was integrated into seen via git@7dd37ea.

@gitgitgadget gitgitgadget Bot added the seen label May 3, 2026
@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented May 3, 2026

There was a status update in the "New Topics" section about the branch mm/line-log-cleanup on the Git mailing list:

Code clean-up.

Comments?
source: <pull.2094.git.1777349126.gitgitgadget@gmail.com>

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented May 4, 2026

This patch series was integrated into seen via git@46c1ebf.

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented May 9, 2026

This patch series was integrated into seen via git@a143674.

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented May 9, 2026

This patch series was integrated into seen via git@f406f5f.

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented May 11, 2026

This patch series was integrated into seen via git@ec1873e.

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented May 11, 2026

There was a status update in the "Cooking" section about the branch mm/line-log-cleanup on the Git mailing list:

Code clean-up.

Comments?
source: <pull.2094.git.1777349126.gitgitgadget@gmail.com>

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented May 11, 2026

This patch series was integrated into seen via git@eb9f7d5.

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented May 11, 2026

This patch series was integrated into seen via git@9781aa1.

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented May 12, 2026

Junio C Hamano wrote on the Git mailing list (how to reply to this email):

"Michael Montalbo via GitGitGadget" <gitgitgadget@gmail.com> writes:

> Since its introduction, git log -L has short-circuited from
> log_tree_commit() into its own output function, bypassing log_tree_diff()
> and log_tree_diff_flush(). This skips no_free save/restore,
> always_show_header, diff_free() cleanup, and means that pickaxe (-S, -G,
> --find-object) and --diff-filter cannot suppress commits whose pairs are all
> filtered out, because show_log() runs before diffcore_std().
>
> This series restructures the flow so that -L goes through the same
> log_tree_diff() -> log_tree_diff_flush() path as normal single-parent and
> merge diffs, then uses that to enable several non-patch diff formats.

This unfortunately saw no reviews and

  https://lore.kernel.org/git/pull.2094.git.1777349126.gitgitgadget@gmail.com/

does not show the previous rouns so I am assuming nobody is
interested in the topic?  

Or are people more busily writing their own patches than reviewing
others' patches?  Unfortunately that is not sustainable.




> Patch 1: revision: move -L setup before output_format-to-diff derivation
>
> Preparatory reorder in setup_revisions(). The -L block sets a default
> DIFF_FORMAT_PATCH when no format is requested; move it before the derivation
> of revs->diff from output_format so the default is visible to that check. No
> behavior change on its own.
>
> Patch 2: line-log: integrate -L output with the standard log-tree pipeline
>
> Rename line_log_print() to line_log_queue_pairs(), stripping it down to only
> queue pre-computed filepairs. log_tree_diff_flush() handles show_log(),
> diffcore_std(), and diff_flush(). This fixes pickaxe and --diff-filter
> suppression, and aligns the commit/diff separator with the rest of log
> output. Also rejects --full-diff, which is meaningless when filepairs are
> pre-computed.
>
> Patch 3: line-log: allow non-patch diff formats with -L
>
> Expand the allowlist to accept --raw, --name-only, --name-status, and
> --summary. These only read filepair metadata already set by the line-log
> machinery. Diff stat formats (--stat, --numstat, --shortstat, --dirstat)
> remain blocked because they call compute_diffstat() on full blob content and
> would show whole-file statistics rather than range-scoped ones.
>
> Michael Montalbo (3):
>   revision: move -L setup before output_format-to-diff derivation
>   line-log: integrate -L output with the standard log-tree pipeline
>   line-log: allow non-patch diff formats with -L
>
>  Documentation/line-range-options.adoc         | 10 +-
>  line-log.c                                    | 30 ++----
>  line-log.h                                    |  2 +-
>  log-tree.c                                    |  9 +-
>  revision.c                                    | 25 +++--
>  t/t4211-line-log.sh                           | 99 ++++++++++++++++---
>  t/t4211/sha1/expect.parallel-change-f-to-main |  1 -
>  .../sha256/expect.parallel-change-f-to-main   |  1 -
>  8 files changed, 120 insertions(+), 57 deletions(-)
>
>
> base-commit: 9f223ef1c026d91c7ac68cc0211bde255dda6199
> Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-2094%2Fmmontalbo%2Fmm%2Fline-log-use-log-tree-diff-flush-v1
> Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-2094/mmontalbo/mm/line-log-use-log-tree-diff-flush-v1
> Pull-Request: https://github.com/gitgitgadget/git/pull/2094

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented May 12, 2026

This patch series was integrated into seen via git@67cdb16.

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented May 12, 2026

There was a status update in the "Cooking" section about the branch mm/line-log-cleanup on the Git mailing list:

Code clean-up.

Comments?
cf. <xmqqfr3xp98b.fsf@gitster.g>
source: <pull.2094.git.1777349126.gitgitgadget@gmail.com>

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented May 13, 2026

This patch series was integrated into seen via git@df46f9d.

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented May 14, 2026

This patch series was integrated into seen via git@3cd0553.

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented May 15, 2026

This patch series was integrated into seen via git@15f8769.

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented May 18, 2026

This patch series was integrated into seen via git@36f0732.

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented May 18, 2026

There was a status update in the "Cooking" section about the branch mm/line-log-cleanup on the Git mailing list:

Code clean-up.

Comments?
cf. <xmqqfr3xp98b.fsf@gitster.g>
source: <pull.2094.git.1777349126.gitgitgadget@gmail.com>

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented May 18, 2026

This patch series was integrated into seen via git@5ac231a.

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented May 19, 2026

This patch series was integrated into seen via git@3c5be57.

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented May 20, 2026

This patch series was integrated into seen via git@0f29831.

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented May 20, 2026

There was a status update in the "Cooking" section about the branch mm/line-log-cleanup on the Git mailing list:

Code clean-up.

Comments?
cf. <xmqqfr3xp98b.fsf@gitster.g>
source: <pull.2094.git.1777349126.gitgitgadget@gmail.com>

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented May 20, 2026

This patch series was integrated into seen via git@cbe78b1.

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented May 21, 2026

This patch series was integrated into seen via git@68e5ad2.

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented May 21, 2026

This patch series was integrated into seen via git@a7f542a.

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented May 21, 2026

This patch series was integrated into seen via git@cbd5b5c.

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented May 22, 2026

"D. Ben Knoble" wrote on the Git mailing list (how to reply to this email):

Hi Michael,

On Tue, Apr 28, 2026 at 12:06 AM Michael Montalbo via GitGitGadget
<gitgitgadget@gmail.com> wrote:
>
> Since its introduction, git log -L has short-circuited from
> log_tree_commit() into its own output function, bypassing log_tree_diff()
> and log_tree_diff_flush(). This skips no_free save/restore,
> always_show_header, diff_free() cleanup, and means that pickaxe (-S, -G,
> --find-object) and --diff-filter cannot suppress commits whose pairs are all
> filtered out, because show_log() runs before diffcore_std().
>
> This series restructures the flow so that -L goes through the same
> log_tree_diff() -> log_tree_diff_flush() path as normal single-parent and
> merge diffs, then uses that to enable several non-patch diff formats.

Cleanup by itself to shrink the number of concepts in the code is
already a good thing IMO, so getting additional features out of it is
even nicer.

> Patch 1: revision: move -L setup before output_format-to-diff derivation
>
> Preparatory reorder in setup_revisions(). The -L block sets a default
> DIFF_FORMAT_PATCH when no format is requested; move it before the derivation
> of revs->diff from output_format so the default is visible to that check. No
> behavior change on its own.

Straightforward, nice.

>
> Patch 2: line-log: integrate -L output with the standard log-tree pipeline
>
> Rename line_log_print() to line_log_queue_pairs(), stripping it down to only
> queue pre-computed filepairs. log_tree_diff_flush() handles show_log(),
> diffcore_std(), and diff_flush(). This fixes pickaxe and --diff-filter
> suppression, and aligns the commit/diff separator with the rest of log
> output. Also rejects --full-diff, which is meaningless when filepairs are
> pre-computed.

At first I questioned the removal of the DIFF_FORMAT_NO_OUTPUT
conditional in line_log_queue_pairs, but now that it only queues pairs
it shouldn't be checking output formats. Good.

I also noted that log_tree_diff() returns the result of
log_tree_diff_flush() in the -L case, which is a bit different from
the other patterns. I think the difference is that the other cases
have some conditional logic around the log_tree_diff_flush cases (?)
but I'm not sure. Perhaps that branch should also be looking at
opt->loginfo ?

Finally, I wonder if in describing the removal of the early return:

> - Remove the early return in log_tree_commit() that bypassed
>   no_free save/restore, always_show_header, and diff_free().

we might want to be more explicit that this is _because_ line-level
diff is now handled in the regular pipeline?

[I suppose we could, in theory, split the rejection of --full-diff to
a separate prep commit, idk.j]

> Patch 3: line-log: allow non-patch diff formats with -L
>
> Expand the allowlist to accept --raw, --name-only, --name-status, and
> --summary. These only read filepair metadata already set by the line-log
> machinery. Diff stat formats (--stat, --numstat, --shortstat, --dirstat)
> remain blocked because they call compute_diffstat() on full blob content and
> would show whole-file statistics rather than range-scoped ones.

Short and sweet.

The stat formats are kind of like --full-diff, and I think they should
probably all be rejected or all allowed: since the stats are based on
the full-diff, it makes sense to enable them if we can also make -L +
--full-diff semantically sensible.

Otherwise, we'd need to find a way to make the stat formats scoped for -L.

> Michael Montalbo (3):
>   revision: move -L setup before output_format-to-diff derivation
>   line-log: integrate -L output with the standard log-tree pipeline
>   line-log: allow non-patch diff formats with -L
>
>  Documentation/line-range-options.adoc         | 10 +-
>  line-log.c                                    | 30 ++----
>  line-log.h                                    |  2 +-
>  log-tree.c                                    |  9 +-
>  revision.c                                    | 25 +++--
>  t/t4211-line-log.sh                           | 99 ++++++++++++++++---
>  t/t4211/sha1/expect.parallel-change-f-to-main |  1 -
>  .../sha256/expect.parallel-change-f-to-main   |  1 -
>  8 files changed, 120 insertions(+), 57 deletions(-)
>
>
> base-commit: 9f223ef1c026d91c7ac68cc0211bde255dda6199
> Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-2094%2Fmmontalbo%2Fmm%2Fline-log-use-log-tree-diff-flush-v1
> Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-2094/mmontalbo/mm/line-log-use-log-tree-diff-flush-v1
> Pull-Request: https://github.com/gitgitgadget/git/pull/2094
> --
> gitgitgadget

A few other comments:

- Tests should use test_grep; some do, but some don't.
- There is one occurrence of "sed | grep" that I wonder if we want to
rewrite to avoid issues with exit status one side of the pipe?

Thanks for working on this!

[Apologies for the unusual review format; this was easier for me at
the moment than digging up the individual patches, and I don't think
_most_ of the review would benefit from spreading out across multiple
mails.]

-- 
D. Ben Knoble

@gitgitgadget
Copy link
Copy Markdown

gitgitgadget Bot commented May 22, 2026

User "D. Ben Knoble" <ben.knoble@gmail.com> has been added to the cc: list.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant