By default the setting 'merge.defaultToUpstream' for git-merge(1) is set
to 'true', which means when `git merge` is invoked with no arguments it
merges the upstream branch configured for the current branch.
With this configuration set to 'true', setup_with_upstream() is called.
That function allocates an array of arguments and hands it back to
cmd_merge() via its `argv` parameter. This array is never freed, so
cmd_merge() leaks it on every invocation.
Track the allocated array in a separate variable and free it at the end.
The leak has been present since
93e535a5b7 (merge: merge with the
default upstream branch without argument, 2011-03-24). Although the leak
sanitizer was enabled for tests in
fc1ddf42af (t: remove
TEST_PASSES_SANITIZE_LEAK annotations, 2024-11-21), it went unnoticed
because no test calls `git merge` without arguments, exercising the
default-to-upstream path. Add such a test in t7600, which fails under
the leak sanitizer without this fix.
Signed-off-by: Toon Claes <toon@iotcl.com>
Acked-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
struct commit_list *common = NULL;
const char *best_strategy = NULL, *wt_strategy = NULL;
struct commit_list *remoteheads = NULL, *p;
- void *branch_to_free;
+ void *branch_to_free, *argv_to_free = NULL;
int orig_argc = argc;
int merge_log_config = -1;
option_commit = 1;
if (!argc) {
- if (default_to_upstream)
+ if (default_to_upstream) {
argc = setup_with_upstream(&argv);
+ argv_to_free = argv;
+ }
else
die(_("No commit specified and merge.defaultToUpstream not set."));
} else if (argc == 1 && !strcmp(argv[0], "-")) {
}
strbuf_release(&buf);
free(branch_to_free);
+ free(argv_to_free);
free(pull_twohead);
free(pull_octopus);
discard_index(the_repository->index);
grep remotes/origin/not-local stderr
'
+test_expect_success 'merge with no argument defaults to upstream' '
+ test_when_finished "rm -rf upstream downstream" &&
+ git init upstream &&
+ (
+ cd upstream &&
+ test_commit one &&
+ test_commit two
+ ) &&
+ git clone upstream downstream &&
+ (
+ cd downstream &&
+ git reset --hard HEAD^ &&
+ git merge &&
+ test_cmp_rev origin/main HEAD
+ )
+'
+
test_done