static void line_log_data_clear(struct line_log_data *r)
{
range_set_release(&r->ranges);
+ free(r->path);
if (r->pair)
diff_free_filepair(r->pair);
+ diff_ranges_release(&r->diff);
}
static void free_line_log_data(struct line_log_data *r)
struct line_log_data *p;
for_each_string_list_item(item, args) {
- const char *name_part, *range_part;
+ const char *name_part;
+ char *range_part;
char *full_name;
struct diff_filespec *spec;
long begin = 0, end = 0;
free_filespec(spec);
FREE_AND_NULL(ends);
+ free(range_part);
}
for (p = ranges; p; p = p->next)
{
struct line_log_data *r;
struct strvec array = STRVEC_INIT;
- const char **paths;
for (r = range; r; r = r->next)
strvec_push(&array, r->path);
- paths = strvec_detach(&array);
- parse_pathspec(pathspec, 0, PATHSPEC_PREFER_FULL, "", paths);
- /* strings are now owned by pathspec */
- free(paths);
+ parse_pathspec(pathspec, 0, PATHSPEC_PREFER_FULL, "", array.v);
+
+ strvec_clear(&array);
}
void line_log_init(struct rev_info *rev, const char *prefix, struct string_list *args)
add_line_range(rev, commit, range);
parse_pathspec_from_ranges(&rev->diffopt.pathspec, range);
+
+ free_line_log_data(range);
}
static void move_diff_queue(struct diff_queue_struct *dst,
while (rg && strcmp(rg->path, pair->two->path))
rg = rg->next;
assert(rg);
+ if (rg->pair)
+ diff_free_filepair(rg->pair);
rg->pair = diff_filepair_dup(queue->queue[i]);
+ diff_ranges_release(&rg->diff);
memcpy(&rg->diff, pairdiff, sizeof(struct diff_ranges));
+ FREE_AND_NULL(pairdiff);
+ }
+
+ if (pairdiff) {
+ diff_ranges_release(pairdiff);
+ free(pairdiff);
}
- free(pairdiff);
}
return changed;
struct commit_list *p;
int i;
int nparents = commit_list_count(commit->parents);
+ int ret;
if (nparents > 1 && rev->first_parent_only)
nparents = 1;
ALLOC_ARRAY(diffqueues, nparents);
- ALLOC_ARRAY(cand, nparents);
+ CALLOC_ARRAY(cand, nparents);
ALLOC_ARRAY(parents, nparents);
p = commit->parents;
for (i = 0; i < nparents; i++) {
int changed;
- cand[i] = NULL;
changed = process_all_files(&cand[i], rev, &diffqueues[i], range);
if (!changed) {
/*
* don't follow any other path in history
*/
add_line_range(rev, parents[i], cand[i]);
- clear_commit_line_range(rev, commit);
commit_list_append(parents[i], &commit->parents);
- free(parents);
- free(cand);
- free_diffqueues(nparents, diffqueues);
- /* NEEDSWORK leaking like a sieve */
- return 0;
+
+ ret = 0;
+ goto out;
}
}
* No single parent took the blame. We add the candidates
* from the above loop to the parents.
*/
- for (i = 0; i < nparents; i++) {
+ for (i = 0; i < nparents; i++)
add_line_range(rev, parents[i], cand[i]);
- }
+ ret = 1;
+
+out:
clear_commit_line_range(rev, commit);
free(parents);
+ for (i = 0; i < nparents; i++) {
+ if (!cand[i])
+ continue;
+ line_log_data_clear(cand[i]);
+ free(cand[i]);
+ }
free(cand);
free_diffqueues(nparents, diffqueues);
- return 1;
+ return ret;
/* NEEDSWORK evil merge detection stuff */
- /* NEEDSWORK leaking like a sieve */
}
int line_log_process_ranges_arbitrary_commit(struct rev_info *rev, struct commit *commit)