From: Junio C Hamano Date: Wed, 15 Nov 2017 03:14:32 +0000 (+0900) Subject: Merge branch 'ma/reduce-heads-leakfix' X-Git-Tag: v2.16.0-rc0~127 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/905f16dd02bb15e0c1e12bf1a6c28510f504f441?ds=inline;hp=-c Merge branch 'ma/reduce-heads-leakfix' Leak fixes. * ma/reduce-heads-leakfix: reduce_heads: fix memory leaks builtin/merge-base: free commit lists --- 905f16dd02bb15e0c1e12bf1a6c28510f504f441 diff --combined builtin/commit.c index cfb78fcf68,11c4740185..8a87701414 --- a/builtin/commit.c +++ b/builtin/commit.c @@@ -118,7 -118,7 +118,7 @@@ static int edit_flag = -1; /* unspecifi static int quiet, verbose, no_verify, allow_empty, dry_run, renew_authorship; static int config_commit_verbose = -1; /* unspecified */ static int no_post_rewrite, allow_empty_message; -static char *untracked_files_arg, *force_date, *ignore_submodule_arg; +static char *untracked_files_arg, *force_date, *ignore_submodule_arg, *ignored_arg; static char *sign_commit; /* @@@ -139,7 -139,7 +139,7 @@@ static const char *cleanup_arg static enum commit_whence whence; static int sequencer_in_use; static int use_editor = 1, include_status = 1; -static int show_ignored_in_status, have_option_m; +static int have_option_m; static struct strbuf message = STRBUF_INIT; static enum wt_status_format status_format = STATUS_FORMAT_UNSPECIFIED; @@@ -355,7 -355,7 +355,7 @@@ static const char *prepare_index(int ar refresh_cache_or_die(refresh_flags); - if (write_locked_index(&the_index, &index_lock, CLOSE_LOCK)) + if (write_locked_index(&the_index, &index_lock, 0)) die(_("unable to create temporary index")); old_index_env = getenv(INDEX_ENVIRONMENT); @@@ -374,7 -374,7 +374,7 @@@ if (update_main_cache_tree(WRITE_TREE_SILENT) == 0) { if (reopen_lock_file(&index_lock) < 0) die(_("unable to write index file")); - if (write_locked_index(&the_index, &index_lock, CLOSE_LOCK)) + if (write_locked_index(&the_index, &index_lock, 0)) die(_("unable to update temporary index")); } else warning(_("Failed to update main cache tree")); @@@ -401,7 -401,7 +401,7 @@@ add_files_to_cache(also ? prefix : NULL, &pathspec, 0); refresh_cache_or_die(refresh_flags); update_main_cache_tree(WRITE_TREE_SILENT); - if (write_locked_index(&the_index, &index_lock, CLOSE_LOCK)) + if (write_locked_index(&the_index, &index_lock, 0)) die(_("unable to write new_index file")); commit_style = COMMIT_NORMAL; ret = get_lock_file_path(&index_lock); @@@ -474,7 -474,7 +474,7 @@@ add_remove_files(&partial); refresh_cache(REFRESH_QUIET); update_main_cache_tree(WRITE_TREE_SILENT); - if (write_locked_index(&the_index, &index_lock, CLOSE_LOCK)) + if (write_locked_index(&the_index, &index_lock, 0)) die(_("unable to write new_index file")); hold_lock_file_for_update(&false_lock, @@@ -486,7 -486,7 +486,7 @@@ add_remove_files(&partial); refresh_cache(REFRESH_QUIET); - if (write_locked_index(&the_index, &false_lock, CLOSE_LOCK)) + if (write_locked_index(&the_index, &false_lock, 0)) die(_("unable to write temporary index file")); discard_cache(); @@@ -912,12 -912,11 +912,12 @@@ static int prepare_to_commit(const cha * submodules which were manually staged, which would * be really confusing. */ - int diff_flags = DIFF_OPT_OVERRIDE_SUBMODULE_CONFIG; + struct diff_flags flags = DIFF_FLAGS_INIT; + flags.override_submodule_config = 1; if (ignore_submodule_arg && !strcmp(ignore_submodule_arg, "all")) - diff_flags |= DIFF_OPT_IGNORE_SUBMODULES; - commitable = index_differs_from(parent, diff_flags, 1); + flags.ignore_submodules = 1; + commitable = index_differs_from(parent, &flags, 1); } } strbuf_release(&committer_ident); @@@ -1076,19 -1075,6 +1076,19 @@@ static const char *find_author_by_nickn die(_("--author '%s' is not 'Name ' and matches no existing author"), name); } +static void handle_ignored_arg(struct wt_status *s) +{ + if (!ignored_arg) + ; /* default already initialized */ + else if (!strcmp(ignored_arg, "traditional")) + s->show_ignored_mode = SHOW_TRADITIONAL_IGNORED; + else if (!strcmp(ignored_arg, "no")) + s->show_ignored_mode = SHOW_NO_IGNORED; + else if (!strcmp(ignored_arg, "matching")) + s->show_ignored_mode = SHOW_MATCHING_IGNORED; + else + die(_("Invalid ignored mode '%s'"), ignored_arg); +} static void handle_untracked_files_arg(struct wt_status *s) { @@@ -1377,10 -1363,8 +1377,10 @@@ int cmd_status(int argc, const char **a N_("mode"), N_("show untracked files, optional modes: all, normal, no. (Default: all)"), PARSE_OPT_OPTARG, NULL, (intptr_t)"all" }, - OPT_BOOL(0, "ignored", &show_ignored_in_status, - N_("show ignored files")), + { OPTION_STRING, 0, "ignored", &ignored_arg, + N_("mode"), + N_("show ignored files, optional modes: traditional, matching, no. (Default: traditional)"), + PARSE_OPT_OPTARG, NULL, (intptr_t)"traditional" }, { OPTION_STRING, 0, "ignore-submodules", &ignore_submodule_arg, N_("when"), N_("ignore changes to submodules, optional when: all, dirty, untracked. (Default: all)"), PARSE_OPT_OPTARG, NULL, (intptr_t)"all" }, @@@ -1399,12 -1383,8 +1399,12 @@@ finalize_deferred_config(&s); handle_untracked_files_arg(&s); - if (show_ignored_in_status) - s.show_ignored_files = 1; + handle_ignored_arg(&s); + + if (s.show_ignored_mode == SHOW_MATCHING_IGNORED && + s.show_untracked_files == SHOW_NO_UNTRACKED_FILES) + die(_("Unsupported combination of ignored and untracked-files arguments")); + parse_pathspec(&s.pathspec, 0, PATHSPEC_PREFER_FULL, prefix, argv); @@@ -1512,8 -1492,6 +1512,8 @@@ static void print_summary(const char *p diff_setup_done(&rev.diffopt); head = resolve_ref_unsafe("HEAD", 0, NULL, NULL); + if (!head) + die_errno(_("unable to resolve HEAD after creating commit")); if (!strcmp(head, "HEAD")) head = _("detached HEAD"); else @@@ -1750,7 -1728,7 +1750,7 @@@ int cmd_commit(int argc, const char **a allow_fast_forward = 0; } if (allow_fast_forward) - parents = reduce_heads(parents); + reduce_heads_replace(&parents); } else { if (!reflog_msg) reflog_msg = (whence == FROM_CHERRY_PICK) @@@ -1810,9 -1788,9 +1810,9 @@@ transaction = ref_transaction_begin(&err); if (!transaction || - ref_transaction_update(transaction, "HEAD", oid.hash, + ref_transaction_update(transaction, "HEAD", &oid, current_head - ? current_head->object.oid.hash : null_sha1, + ? ¤t_head->object.oid : &null_oid, 0, sb.buf, &err) || ref_transaction_commit(transaction, &err)) { rollback_index_files(); diff --combined builtin/fmt-merge-msg.c index b69f7d3be2,27a2361e91..22034f87e7 --- a/builtin/fmt-merge-msg.c +++ b/builtin/fmt-merge-msg.c @@@ -571,7 -571,7 +571,7 @@@ static void find_merge_parents(struct m head_commit = lookup_commit(head); if (head_commit) commit_list_insert(head_commit, &parents); - parents = reduce_heads(parents); + reduce_heads_replace(&parents); while (parents) { struct commit *cmit = pop_commit(&parents); @@@ -603,7 -603,7 +603,7 @@@ int fmt_merge_msg(struct strbuf *in, st /* get current branch */ current_branch = current_branch_to_free = - resolve_refdup("HEAD", RESOLVE_REF_READING, head_oid.hash, NULL); + resolve_refdup("HEAD", RESOLVE_REF_READING, &head_oid, NULL); if (!current_branch) die("No current branch"); if (starts_with(current_branch, "refs/heads/")) diff --combined builtin/merge-base.c index e99f5405ce,24f6c71935..3b7600150b --- a/builtin/merge-base.c +++ b/builtin/merge-base.c @@@ -9,20 -9,20 +9,20 @@@ static int show_merge_base(struct commit **rev, int rev_nr, int show_all) { - struct commit_list *result; + struct commit_list *result, *r; result = get_merge_bases_many_dirty(rev[0], rev_nr - 1, rev + 1); if (!result) return 1; - while (result) { - printf("%s\n", oid_to_hex(&result->item->object.oid)); + for (r = result; r; r = r->next) { + printf("%s\n", oid_to_hex(&r->item->object.oid)); if (!show_all) - return 0; - result = result->next; + break; } + free_commit_list(result); return 0; } @@@ -51,45 -51,47 +51,47 @@@ static struct commit *get_commit_refere static int handle_independent(int count, const char **args) { - struct commit_list *revs = NULL; - struct commit_list *result; + struct commit_list *revs = NULL, *rev; int i; for (i = count - 1; i >= 0; i--) commit_list_insert(get_commit_reference(args[i]), &revs); - result = reduce_heads(revs); - if (!result) + reduce_heads_replace(&revs); + + if (!revs) return 1; - while (result) { - printf("%s\n", oid_to_hex(&result->item->object.oid)); - result = result->next; - } + for (rev = revs; rev; rev = rev->next) + printf("%s\n", oid_to_hex(&rev->item->object.oid)); + + free_commit_list(revs); return 0; } static int handle_octopus(int count, const char **args, int show_all) { struct commit_list *revs = NULL; - struct commit_list *result; + struct commit_list *result, *rev; int i; for (i = count - 1; i >= 0; i--) commit_list_insert(get_commit_reference(args[i]), &revs); - result = reduce_heads(get_octopus_merge_bases(revs)); + result = get_octopus_merge_bases(revs); + free_commit_list(revs); + reduce_heads_replace(&result); if (!result) return 1; - while (result) { - printf("%s\n", oid_to_hex(&result->item->object.oid)); + for (rev = result; rev; rev = rev->next) { + printf("%s\n", oid_to_hex(&rev->item->object.oid)); if (!show_all) - return 0; - result = result->next; + break; } + free_commit_list(result); return 0; } @@@ -156,7 -158,7 +158,7 @@@ static int handle_fork_point(int argc, struct commit_list *bases; int i, ret = 0; - switch (dwim_ref(argv[0], strlen(argv[0]), oid.hash, &refname)) { + switch (dwim_ref(argv[0], strlen(argv[0]), &oid, &refname)) { case 0: die("No such ref: '%s'", argv[0]); case 1: diff --combined builtin/merge.c index 6071dbfe34,fbbf2a9e5e..612dd7bfb6 --- a/builtin/merge.c +++ b/builtin/merge.c @@@ -405,8 -405,9 +405,8 @@@ static void finish(struct commit *head_ printf(_("No merge message -- not updating HEAD\n")); else { const char *argv_gc_auto[] = { "gc", "--auto", NULL }; - update_ref(reflog_message.buf, "HEAD", - new_head->hash, head->hash, 0, - UPDATE_REFS_DIE_ON_ERR); + update_ref(reflog_message.buf, "HEAD", new_head, head, + 0, UPDATE_REFS_DIE_ON_ERR); /* * We ignore errors in 'gc --auto', since the * user should see them. @@@ -454,7 -455,7 +454,7 @@@ static void merge_name(const char *remo if (!remote_head) die(_("'%s' does not point to a commit"), remote); - if (dwim_ref(remote, strlen(remote), branch_head.hash, &found_ref) > 0) { + if (dwim_ref(remote, strlen(remote), &branch_head, &found_ref) > 0) { if (starts_with(found_ref, "refs/heads/")) { strbuf_addf(msg, "%s\t\tbranch '%s' of .\n", oid_to_hex(&branch_head), remote); @@@ -998,6 -999,7 +998,7 @@@ static struct commit_list *reduce_paren /* Find what parents to record by checking independent ones. */ parents = reduce_heads(remoteheads); + free_commit_list(remoteheads); remoteheads = NULL; remotes = &remoteheads; @@@ -1142,7 -1144,7 +1143,7 @@@ int cmd_merge(int argc, const char **ar * Check if we are _not_ on a detached HEAD, i.e. if there is a * current branch. */ - branch = branch_to_free = resolve_refdup("HEAD", 0, head_oid.hash, NULL); + branch = branch_to_free = resolve_refdup("HEAD", 0, &head_oid, NULL); if (branch) skip_prefix(branch, "refs/heads/", &branch); if (!branch || is_null_oid(&head_oid)) @@@ -1260,8 -1262,8 +1261,8 @@@ die(_("Can merge only exactly one commit into empty head")); remote_head_oid = &remoteheads->item->object.oid; read_empty(remote_head_oid->hash, 0); - update_ref("initial pull", "HEAD", remote_head_oid->hash, - NULL, 0, UPDATE_REFS_DIE_ON_ERR); + update_ref("initial pull", "HEAD", remote_head_oid, NULL, 0, + UPDATE_REFS_DIE_ON_ERR); goto done; } @@@ -1356,8 -1358,8 +1357,8 @@@ free(list); } - update_ref("updating ORIG_HEAD", "ORIG_HEAD", head_commit->object.oid.hash, - NULL, 0, UPDATE_REFS_DIE_ON_ERR); + update_ref("updating ORIG_HEAD", "ORIG_HEAD", + &head_commit->object.oid, NULL, 0, UPDATE_REFS_DIE_ON_ERR); if (remoteheads && !common) { /* No common ancestors found. */ diff --combined builtin/pull.c index a28f0ffadd,4edab228eb..f7e2c4f2ec --- a/builtin/pull.c +++ b/builtin/pull.c @@@ -86,7 -86,6 +86,7 @@@ static int recurse_submodules = RECURSE static enum rebase_type opt_rebase = -1; static char *opt_diffstat; static char *opt_log; +static char *opt_signoff; static char *opt_squash; static char *opt_commit; static char *opt_edit; @@@ -143,9 -142,6 +143,9 @@@ static struct option pull_options[] = OPT_PASSTHRU(0, "log", &opt_log, N_("n"), N_("add (at most ) entries from shortlog to merge commit message"), PARSE_OPT_OPTARG), + OPT_PASSTHRU(0, "signoff", &opt_signoff, NULL, + N_("add Signed-off-by:"), + PARSE_OPT_OPTARG), OPT_PASSTHRU(0, "squash", &opt_squash, NULL, N_("create a single commit instead of doing a merge"), PARSE_OPT_NOARG), @@@ -548,7 -544,7 +548,7 @@@ static int pull_into_void(const struct if (checkout_fast_forward(&empty_tree_oid, merge_head, 0)) return 1; - if (update_ref("initial pull", "HEAD", merge_head->hash, curr_head->hash, 0, UPDATE_REFS_DIE_ON_ERR)) + if (update_ref("initial pull", "HEAD", merge_head, curr_head, 0, UPDATE_REFS_DIE_ON_ERR)) return 1; return 0; @@@ -598,8 -594,6 +598,8 @@@ static int run_merge(void argv_array_push(&args, opt_diffstat); if (opt_log) argv_array_push(&args, opt_log); + if (opt_signoff) + argv_array_push(&args, opt_signoff); if (opt_squash) argv_array_push(&args, opt_squash); if (opt_commit) @@@ -751,12 -745,15 +751,15 @@@ static int get_octopus_merge_base(struc if (!is_null_oid(fork_point)) commit_list_insert(lookup_commit_reference(fork_point), &revs); - result = reduce_heads(get_octopus_merge_bases(revs)); + result = get_octopus_merge_bases(revs); free_commit_list(revs); + reduce_heads_replace(&result); + if (!result) return 1; oidcpy(merge_base, &result->item->object.oid); + free_commit_list(result); return 0; }