Skip to content

Commit 3e0d79d

Browse files
sunshinecogitster
authored andcommitted
log: teach -L/RE/ to search from end of previous -L range
This is complicated slightly by having to remember the previous -L range for each file specified via -L<range>:file. The existing implementation coalesces ranges for each file as each -L is parsed which makes it impossible to refer back to the previous -L range for any particular file. Re-implement to instead store each file's set of -L ranges verbatim, and then coalesce the ranges in a post-processing step. Signed-off-by: Eric Sunshine <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 52f4d12 commit 3e0d79d

File tree

1 file changed

+12
-3
lines changed

1 file changed

+12
-3
lines changed

line-log.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -291,15 +291,13 @@ static void line_log_data_insert(struct line_log_data **list,
291291

292292
if (p) {
293293
range_set_append_unsafe(&p->ranges, begin, end);
294-
sort_and_merge_range_set(&p->ranges);
295294
free(path);
296295
return;
297296
}
298297

299298
p = xcalloc(1, sizeof(struct line_log_data));
300299
p->path = path;
301300
range_set_append(&p->ranges, begin, end);
302-
sort_and_merge_range_set(&p->ranges);
303301
if (ip) {
304302
p->next = ip->next;
305303
ip->next = p;
@@ -566,12 +564,14 @@ parse_lines(struct commit *commit, const char *prefix, struct string_list *args)
566564
struct nth_line_cb cb_data;
567565
struct string_list_item *item;
568566
struct line_log_data *ranges = NULL;
567+
struct line_log_data *p;
569568

570569
for_each_string_list_item(item, args) {
571570
const char *name_part, *range_part;
572571
char *full_name;
573572
struct diff_filespec *spec;
574573
long begin = 0, end = 0;
574+
long anchor;
575575

576576
name_part = skip_range_arg(item->string);
577577
if (!name_part || *name_part != ':' || !name_part[1])
@@ -590,8 +590,14 @@ parse_lines(struct commit *commit, const char *prefix, struct string_list *args)
590590
cb_data.lines = lines;
591591
cb_data.line_ends = ends;
592592

593+
p = search_line_log_data(ranges, full_name, NULL);
594+
if (p && p->ranges.nr)
595+
anchor = p->ranges.ranges[p->ranges.nr - 1].end + 1;
596+
else
597+
anchor = 1;
598+
593599
if (parse_range_arg(range_part, nth_line, &cb_data,
594-
lines, 1, &begin, &end,
600+
lines, anchor, &begin, &end,
595601
full_name))
596602
die("malformed -L argument '%s'", range_part);
597603
if (lines < end || ((lines || begin) && lines < begin))
@@ -608,6 +614,9 @@ parse_lines(struct commit *commit, const char *prefix, struct string_list *args)
608614
ends = NULL;
609615
}
610616

617+
for (p = ranges; p; p = p->next)
618+
sort_and_merge_range_set(&p->ranges);
619+
611620
return ranges;
612621
}
613622

0 commit comments

Comments
 (0)