Skip to content

Commit c039684

Browse files
committed
Merge branch 'sg/line-log-merge-optim'
"git log -L..." compared trees of multiple parents with the tree of the merge result in an unnecessarily inefficient way. * sg/line-log-merge-optim: line-log: simplify condition checking for merge commits line-log: initialize diff queue in process_ranges_ordinary_commit() line-log: get rid of the parents array in process_ranges_merge_commit() line-log: avoid unnecessary tree diffs when processing merge commits
2 parents dd2a0d9 + 0a15bb6 commit c039684

File tree

1 file changed

+20
-30
lines changed

1 file changed

+20
-30
lines changed

line-log.c

Lines changed: 20 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1087,13 +1087,6 @@ static struct diff_filepair *diff_filepair_dup(struct diff_filepair *pair)
10871087
return new_filepair;
10881088
}
10891089

1090-
static void free_diffqueues(int n, struct diff_queue_struct *dq)
1091-
{
1092-
for (int i = 0; i < n; i++)
1093-
diff_queue_clear(&dq[i]);
1094-
free(dq);
1095-
}
1096-
10971090
static int process_all_files(struct line_log_data **range_out,
10981091
struct rev_info *rev,
10991092
struct diff_queue_struct *queue,
@@ -1189,7 +1182,7 @@ static int process_ranges_ordinary_commit(struct rev_info *rev, struct commit *c
11891182
struct line_log_data *range)
11901183
{
11911184
struct commit *parent = NULL;
1192-
struct diff_queue_struct queue;
1185+
struct diff_queue_struct queue = DIFF_QUEUE_INIT;
11931186
struct line_log_data *parent_range;
11941187
int changed;
11951188

@@ -1209,9 +1202,7 @@ static int process_ranges_ordinary_commit(struct rev_info *rev, struct commit *c
12091202
static int process_ranges_merge_commit(struct rev_info *rev, struct commit *commit,
12101203
struct line_log_data *range)
12111204
{
1212-
struct diff_queue_struct *diffqueues;
12131205
struct line_log_data **cand;
1214-
struct commit **parents;
12151206
struct commit_list *p;
12161207
int i;
12171208
int nparents = commit_list_count(commit->parents);
@@ -1220,28 +1211,27 @@ static int process_ranges_merge_commit(struct rev_info *rev, struct commit *comm
12201211
if (nparents > 1 && rev->first_parent_only)
12211212
nparents = 1;
12221213

1223-
ALLOC_ARRAY(diffqueues, nparents);
12241214
CALLOC_ARRAY(cand, nparents);
1225-
ALLOC_ARRAY(parents, nparents);
1226-
1227-
p = commit->parents;
1228-
for (i = 0; i < nparents; i++) {
1229-
parents[i] = p->item;
1230-
p = p->next;
1231-
queue_diffs(range, &rev->diffopt, &diffqueues[i], commit, parents[i]);
1232-
}
12331215

1234-
for (i = 0; i < nparents; i++) {
1216+
for (p = commit->parents, i = 0;
1217+
p && i < nparents;
1218+
p = p->next, i++) {
1219+
struct commit *parent = p->item;
1220+
struct diff_queue_struct diffqueue = DIFF_QUEUE_INIT;
12351221
int changed;
1236-
changed = process_all_files(&cand[i], rev, &diffqueues[i], range);
1222+
1223+
queue_diffs(range, &rev->diffopt, &diffqueue, commit, parent);
1224+
1225+
changed = process_all_files(&cand[i], rev, &diffqueue, range);
1226+
diff_queue_clear(&diffqueue);
12371227
if (!changed) {
12381228
/*
12391229
* This parent can take all the blame, so we
12401230
* don't follow any other path in history
12411231
*/
1242-
add_line_range(rev, parents[i], cand[i]);
1232+
add_line_range(rev, parent, cand[i]);
12431233
free_commit_list(commit->parents);
1244-
commit_list_append(parents[i], &commit->parents);
1234+
commit_list_append(parent, &commit->parents);
12451235

12461236
ret = 0;
12471237
goto out;
@@ -1252,22 +1242,22 @@ static int process_ranges_merge_commit(struct rev_info *rev, struct commit *comm
12521242
* No single parent took the blame. We add the candidates
12531243
* from the above loop to the parents.
12541244
*/
1255-
for (i = 0; i < nparents; i++)
1256-
add_line_range(rev, parents[i], cand[i]);
1245+
for (p = commit->parents, i = 0;
1246+
p && i < nparents;
1247+
p = p->next, i++)
1248+
add_line_range(rev, p->item, cand[i]);
12571249

12581250
ret = 1;
12591251

12601252
out:
12611253
clear_commit_line_range(rev, commit);
1262-
free(parents);
12631254
for (i = 0; i < nparents; i++) {
12641255
if (!cand[i])
12651256
continue;
12661257
line_log_data_clear(cand[i]);
12671258
free(cand[i]);
12681259
}
12691260
free(cand);
1270-
free_diffqueues(nparents, diffqueues);
12711261
return ret;
12721262

12731263
/* NEEDSWORK evil merge detection stuff */
@@ -1283,10 +1273,10 @@ int line_log_process_ranges_arbitrary_commit(struct rev_info *rev, struct commit
12831273
struct line_log_data *prange = line_log_data_copy(range);
12841274
add_line_range(rev, commit->parents->item, prange);
12851275
clear_commit_line_range(rev, commit);
1286-
} else if (!commit->parents || !commit->parents->next)
1287-
changed = process_ranges_ordinary_commit(rev, commit, range);
1288-
else
1276+
} else if (commit->parents && commit->parents->next)
12891277
changed = process_ranges_merge_commit(rev, commit, range);
1278+
else
1279+
changed = process_ranges_ordinary_commit(rev, commit, range);
12901280
}
12911281

12921282
if (!changed)

0 commit comments

Comments
 (0)