Files
git/line-log.h
Michael Montalbo 42d960748e line-log: integrate -L output with the standard log-tree pipeline
`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
f8781bfda3), 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 is no longer
   needed now that -L output flows through log_tree_diff() and
   log_tree_diff_flush(); this restores no_free save/restore,
   always_show_header, and diff_free() cleanup.

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 not yet supported with -L: the
filepairs are pre-computed during the history walk and scoped to
tracked line ranges, so there is currently no full-tree diff to
fall back to for display.

Update tests accordingly.

Signed-off-by: Michael Montalbo <mmontalbo@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-05-29 14:06:21 +09:00

54 lines
1.6 KiB
C

#ifndef LINE_LOG_H
#define LINE_LOG_H
#include "diffcore.h" /* struct range, struct range_set */
struct rev_info;
struct commit;
struct string_list;
/* A diff, encoded as the set of pre- and post-image ranges where the
* files differ. A pair of ranges corresponds to a hunk. */
struct diff_ranges {
struct range_set parent;
struct range_set target;
};
void range_set_init(struct range_set *, size_t prealloc);
void range_set_release(struct range_set *);
/* Range includes start; excludes end */
void range_set_append_unsafe(struct range_set *, long start, long end);
/* New range must begin at or after end of last added range */
void range_set_append(struct range_set *, long start, long end);
/*
* In-place pass of sorting and merging the ranges in the range set,
* to sort and make the ranges disjoint.
*/
void sort_and_merge_range_set(struct range_set *);
/* Linked list of interesting files and their associated ranges. The
* list must be kept sorted by path.
*
* For simplicity, even though this is highly redundant, each
* line_log_data owns its 'path'.
*/
struct line_log_data {
struct line_log_data *next;
char *path;
struct range_set ranges;
struct diff_filepair *pair;
struct diff_ranges diff;
};
void line_log_init(struct rev_info *rev, const char *prefix, struct string_list *args);
int line_log_filter(struct rev_info *rev);
int line_log_process_ranges_arbitrary_commit(struct rev_info *rev,
struct commit *commit);
void line_log_queue_pairs(struct rev_info *rev, struct commit *commit);
void line_log_free(struct rev_info *rev);
#endif /* LINE_LOG_H */