diff options
Diffstat (limited to 'line-log.c')
| -rw-r--r-- | line-log.c | 65 |
1 files changed, 32 insertions, 33 deletions
diff --git a/line-log.c b/line-log.c index 07f2154e84..8bd422148d 100644 --- a/line-log.c +++ b/line-log.c @@ -201,7 +201,7 @@ static void range_set_difference(struct range_set *out, * b: ------| */ j++; - if (j >= b->nr || end < b->ranges[j].start) { + if (j >= b->nr || end <= b->ranges[j].start) { /* * b exhausted, or * a: ----| @@ -408,7 +408,7 @@ static void diff_ranges_filter_touched(struct diff_ranges *out, assert(out->target.nr == 0); for (i = 0; i < diff->target.nr; i++) { - while (diff->target.ranges[i].start > rs->ranges[j].end) { + while (diff->target.ranges[i].start >= rs->ranges[j].end) { j++; if (j == rs->nr) return; @@ -939,9 +939,18 @@ static void dump_diff_hacky_one(struct rev_info *rev, struct line_log_data *rang long t_cur = t_start; unsigned int j_last; + /* + * If a diff range touches multiple line ranges, then all + * those line ranges should be shown, so take a step back if + * the current line range is still in the previous diff range + * (even if only partially). + */ + if (j > 0 && diff->target.ranges[j-1].end > t_start) + j--; + while (j < diff->target.nr && diff->target.ranges[j].end < t_start) j++; - if (j == diff->target.nr || diff->target.ranges[j].start > t_end) + if (j == diff->target.nr || diff->target.ranges[j].start >= t_end) continue; /* Scan ahead to determine the last diff that falls in this range */ @@ -1087,13 +1096,6 @@ static struct diff_filepair *diff_filepair_dup(struct diff_filepair *pair) return new_filepair; } -static void free_diffqueues(int n, struct diff_queue_struct *dq) -{ - for (int i = 0; i < n; i++) - diff_queue_clear(&dq[i]); - free(dq); -} - static int process_all_files(struct line_log_data **range_out, struct rev_info *rev, struct diff_queue_struct *queue, @@ -1189,7 +1191,7 @@ static int process_ranges_ordinary_commit(struct rev_info *rev, struct commit *c struct line_log_data *range) { struct commit *parent = NULL; - struct diff_queue_struct queue; + struct diff_queue_struct queue = DIFF_QUEUE_INIT; struct line_log_data *parent_range; int changed; @@ -1209,9 +1211,7 @@ static int process_ranges_ordinary_commit(struct rev_info *rev, struct commit *c static int process_ranges_merge_commit(struct rev_info *rev, struct commit *commit, struct line_log_data *range) { - struct diff_queue_struct *diffqueues; struct line_log_data **cand; - struct commit **parents; struct commit_list *p; int i; int nparents = commit_list_count(commit->parents); @@ -1220,28 +1220,27 @@ static int process_ranges_merge_commit(struct rev_info *rev, struct commit *comm if (nparents > 1 && rev->first_parent_only) nparents = 1; - ALLOC_ARRAY(diffqueues, nparents); CALLOC_ARRAY(cand, nparents); - ALLOC_ARRAY(parents, nparents); - p = commit->parents; - for (i = 0; i < nparents; i++) { - parents[i] = p->item; - p = p->next; - queue_diffs(range, &rev->diffopt, &diffqueues[i], commit, parents[i]); - } - - for (i = 0; i < nparents; i++) { + for (p = commit->parents, i = 0; + p && i < nparents; + p = p->next, i++) { + struct commit *parent = p->item; + struct diff_queue_struct diffqueue = DIFF_QUEUE_INIT; int changed; - changed = process_all_files(&cand[i], rev, &diffqueues[i], range); + + queue_diffs(range, &rev->diffopt, &diffqueue, commit, parent); + + changed = process_all_files(&cand[i], rev, &diffqueue, range); + diff_queue_clear(&diffqueue); if (!changed) { /* * This parent can take all the blame, so we * don't follow any other path in history */ - add_line_range(rev, parents[i], cand[i]); + add_line_range(rev, parent, cand[i]); free_commit_list(commit->parents); - commit_list_append(parents[i], &commit->parents); + commit_list_append(parent, &commit->parents); ret = 0; goto out; @@ -1252,14 +1251,15 @@ static int process_ranges_merge_commit(struct rev_info *rev, struct commit *comm * No single parent took the blame. We add the candidates * from the above loop to the parents. */ - for (i = 0; i < nparents; i++) - add_line_range(rev, parents[i], cand[i]); + for (p = commit->parents, i = 0; + p && i < nparents; + p = p->next, i++) + add_line_range(rev, p->item, cand[i]); ret = 1; out: clear_commit_line_range(rev, commit); - free(parents); for (i = 0; i < nparents; i++) { if (!cand[i]) continue; @@ -1267,7 +1267,6 @@ out: free(cand[i]); } free(cand); - free_diffqueues(nparents, diffqueues); return ret; /* NEEDSWORK evil merge detection stuff */ @@ -1283,10 +1282,10 @@ int line_log_process_ranges_arbitrary_commit(struct rev_info *rev, struct commit struct line_log_data *prange = line_log_data_copy(range); add_line_range(rev, commit->parents->item, prange); clear_commit_line_range(rev, commit); - } else if (!commit->parents || !commit->parents->next) - changed = process_ranges_ordinary_commit(rev, commit, range); - else + } else if (commit->parents && commit->parents->next) changed = process_ranges_merge_commit(rev, commit, range); + else + changed = process_ranges_ordinary_commit(rev, commit, range); } if (!changed) |
