Merge branch 'ma/reduce-heads-leakfix'
authorJunio C Hamano <gitster@pobox.com>
Wed, 15 Nov 2017 03:14:32 +0000 (12:14 +0900)
committerJunio C Hamano <gitster@pobox.com>
Wed, 15 Nov 2017 03:14:32 +0000 (12:14 +0900)
Leak fixes.

* ma/reduce-heads-leakfix:
reduce_heads: fix memory leaks
builtin/merge-base: free commit lists

1  2 
builtin/commit.c
builtin/fmt-merge-msg.c
builtin/merge-base.c
builtin/merge.c
builtin/pull.c
diff --combined builtin/commit.c
index cfb78fcf680f4aea96035d0158b2855a1358d674,11c47401854fa4bfd8b75429f053882ff1c61551..8a877014145435516930c787dec37b8c4ac3da90
@@@ -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);
                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"));
                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);
        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,
        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 <email>' 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" },
        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)
  
        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,
 +                                 ? &current_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 b69f7d3be2bd4585a6233d0f8361c55a76ae0a5d,27a2361e91dcd94cba4556b04b028286835f8823..22034f87e7f8c7fa1166d3731319aca610fef2a2
@@@ -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 e99f5405ce34af093323e80676713a6d6a278092,24f6c7193546b91a8644a4417bfc6d6d94da6a62..3b7600150b66c4bf814e21b74b2d931f44c83805
@@@ -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 6071dbfe3466b9c67dcc9b888210cc23816e95d2,fbbf2a9e5eb9be47d8574ca0bab175c5a6c0d15d..612dd7bfb6c7e6ae6f636e0b2e55bfed1aff92f2
@@@ -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))
                        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;
        }
  
                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 a28f0ffadd13dfc207785b61425b35964cb43365,4edab228ebe6c1d3df580689c7cf94eb989fe4bc..f7e2c4f2ecd0ce5c24dce1fceb614d85013810cb
@@@ -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 <n>) 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;
  }