diff options
author | Eric Sunshine <sunshine@sunshineco.com> | 2013-08-06 09:59:43 -0400 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2013-08-06 14:46:12 -0700 |
commit | 3e0d79dbe3064cf065b6518520dd1489406200a9 (patch) | |
tree | 4894504d7bc5b7cc727943170fb3eb9b75c20e53 /line-log.c | |
parent | 52f4d1264854485bfd50afeeed1933a3f9e05c96 (diff) | |
download | git-3e0d79dbe3064cf065b6518520dd1489406200a9.tar.gz |
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 <sunshine@sunshineco.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'line-log.c')
-rw-r--r-- | line-log.c | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/line-log.c b/line-log.c index 38f827ba9a..d40c79dc2b 100644 --- a/line-log.c +++ b/line-log.c @@ -291,7 +291,6 @@ static void line_log_data_insert(struct line_log_data **list, if (p) { range_set_append_unsafe(&p->ranges, begin, end); - sort_and_merge_range_set(&p->ranges); free(path); return; } @@ -299,7 +298,6 @@ static void line_log_data_insert(struct line_log_data **list, p = xcalloc(1, sizeof(struct line_log_data)); p->path = path; range_set_append(&p->ranges, begin, end); - sort_and_merge_range_set(&p->ranges); if (ip) { p->next = ip->next; ip->next = p; @@ -566,12 +564,14 @@ parse_lines(struct commit *commit, const char *prefix, struct string_list *args) struct nth_line_cb cb_data; struct string_list_item *item; struct line_log_data *ranges = NULL; + struct line_log_data *p; for_each_string_list_item(item, args) { const char *name_part, *range_part; char *full_name; struct diff_filespec *spec; long begin = 0, end = 0; + long anchor; name_part = skip_range_arg(item->string); if (!name_part || *name_part != ':' || !name_part[1]) @@ -590,8 +590,14 @@ parse_lines(struct commit *commit, const char *prefix, struct string_list *args) cb_data.lines = lines; cb_data.line_ends = ends; + p = search_line_log_data(ranges, full_name, NULL); + if (p && p->ranges.nr) + anchor = p->ranges.ranges[p->ranges.nr - 1].end + 1; + else + anchor = 1; + if (parse_range_arg(range_part, nth_line, &cb_data, - lines, 1, &begin, &end, + lines, anchor, &begin, &end, full_name)) die("malformed -L argument '%s'", range_part); if (lines < end || ((lines || begin) && lines < begin)) @@ -608,6 +614,9 @@ parse_lines(struct commit *commit, const char *prefix, struct string_list *args) ends = NULL; } + for (p = ranges; p; p = p->next) + sort_and_merge_range_set(&p->ranges); + return ranges; } |