cmd_pull() builds a commit_list to pass a single potential ancestor to is_descendant_of(). The latter leaves the list intact. Release the allocated memory after the call. Leaking in cmd_*() isn't a big deal, but sets a bad example for other users of is_descendant_of(). Signed-off-by: René Scharfe <l.s.r@xxxxxx> --- Patch generated with -U15 for easier review; only the pre-context is interesting, though. --function-context would add even more noise. A --block-context option might be nice (include surrounding lines up to and including the previous and next lines with lower indentation). :) Or perhaps it's a sign that the function should be split up.. builtin/pull.c | 1 + 1 file changed, 1 insertion(+) diff --git a/builtin/pull.c b/builtin/pull.c index 00e5857a8d..8e6572d305 100644 --- a/builtin/pull.c +++ b/builtin/pull.c @@ -1019,30 +1019,31 @@ int cmd_pull(int argc, const char **argv, const char *prefix) if (!autostash) { struct commit_list *list = NULL; struct commit *merge_head, *head; head = lookup_commit_reference(the_repository, &orig_head); commit_list_insert(head, &list); merge_head = lookup_commit_reference(the_repository, &merge_heads.oid[0]); if (is_descendant_of(merge_head, list)) { /* we can fast-forward this without invoking rebase */ opt_ff = "--ff-only"; ran_ff = 1; ret = run_merge(); } + free_commit_list(list); } if (!ran_ff) ret = run_rebase(&curr_head, merge_heads.oid, &rebase_fork_point); if (!ret && (recurse_submodules == RECURSE_SUBMODULES_ON || recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND)) ret = rebase_submodules(); return ret; } else { int ret = run_merge(); if (!ret && (recurse_submodules == RECURSE_SUBMODULES_ON || recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND)) ret = update_submodules(); return ret; -- 2.27.0