In diff_tree_combined we make a copy of diffopts. In
try_to_follow_renames, called via diff_tree_sha1, we free and
re-initialize diffopts->pathspec->items. Since we did not make a deep
copy of diffopts in diff_tree_combined, the original diffopts does not
get the update. By the time we return from diff_tree_combined,
rev->diffopt->pathspec->items points to an invalid memory address. We
get a segfault next time we try to access that pathspec.
Instead, along with the copy of diffopts, make a copy pathspec->items as
well.
We would also have to make a copy of pathspec->raw to keep it consistent
with pathspec->items, but nobody seems to rely on that.
Signed-off-by: Clemens Buchacher <drizzd@aon.at>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
int i, num_paths, needsep, show_log_first, num_parent = parents->nr;
diffopts = *opt;
+ diff_tree_setup_paths(diffopts.pathspec.raw, &diffopts);
diffopts.output_format = DIFF_FORMAT_NO_OUTPUT;
DIFF_OPT_SET(&diffopts, RECURSIVE);
DIFF_OPT_CLR(&diffopts, ALLOW_EXTERNAL);
paths = paths->next;
free(tmp);
}
+
+ diff_tree_release_paths(&diffopts);
}
void diff_tree_combined_merge(const struct commit *commit, int dense,
)
'
+test_expect_success 'git log -c --follow' '
+ test_create_repo follow-c &&
+ (
+ cd follow-c &&
+ test_commit initial file original &&
+ git rm file &&
+ test_commit rename file2 original &&
+ git reset --hard initial &&
+ test_commit modify file foo &&
+ git merge -m merge rename &&
+ git log -c --follow file2
+ )
+'
+
cat >expect <<\EOF
* commit COMMIT_OBJECT_NAME
|\ Merge: MERGE_PARENTS