Merge branch 'rs/commit-pptr-simplify'
authorJunio C Hamano <gitster@pobox.com>
Mon, 31 Oct 2016 20:15:25 +0000 (13:15 -0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 31 Oct 2016 20:15:25 +0000 (13:15 -0700)
Code simplification.

* rs/commit-pptr-simplify:
commit: simplify building parents list

1  2 
builtin/commit.c
diff --combined builtin/commit.c
index a2baa6ebd5b2dc1090b1bcc87c1e9cf95abd6398,f6d6c4759da0f0b96ad2a2882cbfa7715a9f888a..8976c3d29bf817be789f983697f7052fe5769f39
@@@ -92,9 -92,8 +92,9 @@@ N_("If you wish to skip this commit, us
  "Then \"git cherry-pick --continue\" will resume cherry-picking\n"
  "the remaining commits.\n");
  
 +static GIT_PATH_FUNC(git_path_commit_editmsg, "COMMIT_EDITMSG")
 +
  static const char *use_message_buffer;
 -static const char commit_editmsg[] = "COMMIT_EDITMSG";
  static struct lock_file index_lock; /* real index */
  static struct lock_file false_lock; /* used only for partial commits */
  static enum {
@@@ -115,7 -114,6 +115,7 @@@ static char *fixup_message, *squash_mes
  static int all, also, interactive, patch_interactive, only, amend, signoff;
  static int edit_flag = -1; /* unspecified */
  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 *sign_commit;
@@@ -142,24 -140,14 +142,24 @@@ static int show_ignored_in_status, have
  static const char *only_include_assumed;
  static struct strbuf message = STRBUF_INIT;
  
 -static enum status_format {
 -      STATUS_FORMAT_NONE = 0,
 -      STATUS_FORMAT_LONG,
 -      STATUS_FORMAT_SHORT,
 -      STATUS_FORMAT_PORCELAIN,
 +static enum wt_status_format status_format = STATUS_FORMAT_UNSPECIFIED;
  
 -      STATUS_FORMAT_UNSPECIFIED
 -} status_format = STATUS_FORMAT_UNSPECIFIED;
 +static int opt_parse_porcelain(const struct option *opt, const char *arg, int unset)
 +{
 +      enum wt_status_format *value = (enum wt_status_format *)opt->value;
 +      if (unset)
 +              *value = STATUS_FORMAT_NONE;
 +      else if (!arg)
 +              *value = STATUS_FORMAT_PORCELAIN;
 +      else if (!strcmp(arg, "v1") || !strcmp(arg, "1"))
 +              *value = STATUS_FORMAT_PORCELAIN;
 +      else if (!strcmp(arg, "v2") || !strcmp(arg, "2"))
 +              *value = STATUS_FORMAT_PORCELAIN_V2;
 +      else
 +              die("unsupported porcelain version '%s'", arg);
 +
 +      return 0;
 +}
  
  static int opt_parse_m(const struct option *opt, const char *arg, int unset)
  {
@@@ -183,7 -171,7 +183,7 @@@ static void determine_whence(struct wt_
                whence = FROM_MERGE;
        else if (file_exists(git_path_cherry_pick_head())) {
                whence = FROM_CHERRY_PICK;
 -              if (file_exists(git_path(SEQ_DIR)))
 +              if (file_exists(git_path_seq_dir()))
                        sequencer_in_use = 1;
        }
        else
@@@ -198,7 -186,6 +198,7 @@@ static void status_init_config(struct w
        gitmodules_config();
        git_config(fn, s);
        determine_whence(s);
 +      init_diff_ui_defaults();
        s->hints = advice_status_hints; /* must come after git_config() */
  }
  
@@@ -510,13 -497,24 +510,13 @@@ static int run_status(FILE *fp, const c
        s->fp = fp;
        s->nowarn = nowarn;
        s->is_initial = get_sha1(s->reference, sha1) ? 1 : 0;
 +      if (!s->is_initial)
 +              hashcpy(s->sha1_commit, sha1);
 +      s->status_format = status_format;
 +      s->ignore_submodule_arg = ignore_submodule_arg;
  
        wt_status_collect(s);
 -
 -      switch (status_format) {
 -      case STATUS_FORMAT_SHORT:
 -              wt_shortstatus_print(s);
 -              break;
 -      case STATUS_FORMAT_PORCELAIN:
 -              wt_porcelain_print(s);
 -              break;
 -      case STATUS_FORMAT_UNSPECIFIED:
 -              die("BUG: finalize_deferred_config() should have been called");
 -              break;
 -      case STATUS_FORMAT_NONE:
 -      case STATUS_FORMAT_LONG:
 -              wt_status_print(s);
 -              break;
 -      }
 +      wt_status_print(s);
  
        return s->commitable;
  }
@@@ -714,7 -712,7 +714,7 @@@ static int prepare_to_commit(const cha
                char *buffer;
                buffer = strstr(use_message_buffer, "\n\n");
                if (buffer)
 -                      strbuf_addstr(&sb, buffer + 2);
 +                      strbuf_addstr(&sb, skip_blank_lines(buffer + 2));
                hook_arg1 = "commit";
                hook_arg2 = use_message;
        } else if (fixup_message) {
                hook_arg2 = "";
        }
  
 -      s->fp = fopen_for_writing(git_path(commit_editmsg));
 +      s->fp = fopen_for_writing(git_path_commit_editmsg());
        if (s->fp == NULL)
 -              die_errno(_("could not open '%s'"), git_path(commit_editmsg));
 +              die_errno(_("could not open '%s'"), git_path_commit_editmsg());
  
        /* Ignore status.displayCommentPrefix: we do need comments in COMMIT_EDITMSG. */
        old_display_comment_prefix = s->display_comment_prefix;
                if (amend)
                        parent = "HEAD^1";
  
 -              if (get_sha1(parent, sha1))
 -                      commitable = !!active_nr;
 -              else {
 +              if (get_sha1(parent, sha1)) {
 +                      int i, ita_nr = 0;
 +
 +                      for (i = 0; i < active_nr; i++)
 +                              if (ce_intent_to_add(active_cache[i]))
 +                                      ita_nr++;
 +                      commitable = active_nr - ita_nr > 0;
 +              } else {
                        /*
                         * Unless the user did explicitly request a submodule
                         * ignore mode by passing a command line option we do
                        if (ignore_submodule_arg &&
                            !strcmp(ignore_submodule_arg, "all"))
                                diff_flags |= DIFF_OPT_IGNORE_SUBMODULES;
 -                      commitable = index_differs_from(parent, diff_flags);
 +                      commitable = index_differs_from(parent, diff_flags, 1);
                }
        }
        strbuf_release(&committer_ident);
        }
  
        if (run_commit_hook(use_editor, index_file, "prepare-commit-msg",
 -                          git_path(commit_editmsg), hook_arg1, hook_arg2, NULL))
 +                          git_path_commit_editmsg(), hook_arg1, hook_arg2, NULL))
                return 0;
  
        if (use_editor) {
                const char *env[2] = { NULL };
                env[0] =  index;
                snprintf(index, sizeof(index), "GIT_INDEX_FILE=%s", index_file);
 -              if (launch_editor(git_path(commit_editmsg), NULL, env)) {
 +              if (launch_editor(git_path_commit_editmsg(), NULL, env)) {
                        fprintf(stderr,
                        _("Please supply the message using either -m or -F option.\n"));
                        exit(1);
        }
  
        if (!no_verify &&
 -          run_commit_hook(use_editor, index_file, "commit-msg", git_path(commit_editmsg), NULL)) {
 +          run_commit_hook(use_editor, index_file, "commit-msg", git_path_commit_editmsg(), NULL)) {
                return 0;
        }
  
@@@ -1103,7 -1096,7 +1103,7 @@@ static const char *read_commit_message(
   * is not in effect here.
   */
  static struct status_deferred_config {
 -      enum status_format status_format;
 +      enum wt_status_format status_format;
        int show_branch;
  } status_deferred_config = {
        STATUS_FORMAT_UNSPECIFIED,
  static void finalize_deferred_config(struct wt_status *s)
  {
        int use_deferred_config = (status_format != STATUS_FORMAT_PORCELAIN &&
 +                                 status_format != STATUS_FORMAT_PORCELAIN_V2 &&
                                   !s->null_termination);
  
        if (s->null_termination) {
@@@ -1341,9 -1333,9 +1341,9 @@@ int cmd_status(int argc, const char **a
                            N_("show status concisely"), STATUS_FORMAT_SHORT),
                OPT_BOOL('b', "branch", &s.show_branch,
                         N_("show branch information")),
 -              OPT_SET_INT(0, "porcelain", &status_format,
 -                          N_("machine-readable output"),
 -                          STATUS_FORMAT_PORCELAIN),
 +              { OPTION_CALLBACK, 0, "porcelain", &status_format,
 +                N_("version"), N_("machine-readable output"),
 +                PARSE_OPT_OPTARG, opt_parse_porcelain },
                OPT_SET_INT(0, "long", &status_format,
                            N_("show status in long format (default)"),
                            STATUS_FORMAT_LONG),
        fd = hold_locked_index(&index_lock, 0);
  
        s.is_initial = get_sha1(s.reference, sha1) ? 1 : 0;
 +      if (!s.is_initial)
 +              hashcpy(s.sha1_commit, sha1);
 +
        s.ignore_submodule_arg = ignore_submodule_arg;
 +      s.status_format = status_format;
 +      s.verbose = verbose;
 +
        wt_status_collect(&s);
  
        if (0 <= fd)
        if (s.relative_paths)
                s.prefix = prefix;
  
 -      switch (status_format) {
 -      case STATUS_FORMAT_SHORT:
 -              wt_shortstatus_print(&s);
 -              break;
 -      case STATUS_FORMAT_PORCELAIN:
 -              wt_porcelain_print(&s);
 -              break;
 -      case STATUS_FORMAT_UNSPECIFIED:
 -              die("BUG: finalize_deferred_config() should have been called");
 -              break;
 -      case STATUS_FORMAT_NONE:
 -      case STATUS_FORMAT_LONG:
 -              s.verbose = verbose;
 -              s.ignore_submodule_arg = ignore_submodule_arg;
 -              wt_status_print(&s);
 -              break;
 -      }
 +      wt_status_print(&s);
        return 0;
  }
  
@@@ -1512,11 -1514,6 +1512,11 @@@ static int git_commit_config(const cha
                sign_commit = git_config_bool(k, v) ? "" : NULL;
                return 0;
        }
 +      if (!strcmp(k, "commit.verbose")) {
 +              int is_bool;
 +              config_commit_verbose = git_config_bool_or_int(k, v, &is_bool);
 +              return 0;
 +      }
  
        status = git_gpg_config(k, v, NULL);
        if (status)
@@@ -1612,7 -1609,7 +1612,7 @@@ int cmd_commit(int argc, const char **a
                OPT_BOOL(0, "interactive", &interactive, N_("interactively add files")),
                OPT_BOOL('p', "patch", &patch_interactive, N_("interactively add changes")),
                OPT_BOOL('o', "only", &only, N_("commit only specified files")),
 -              OPT_BOOL('n', "no-verify", &no_verify, N_("bypass pre-commit hook")),
 +              OPT_BOOL('n', "no-verify", &no_verify, N_("bypass pre-commit and commit-msg hooks")),
                OPT_BOOL(0, "dry-run", &dry_run, N_("show what would be committed")),
                OPT_SET_INT(0, "short", &status_format, N_("show status concisely"),
                            STATUS_FORMAT_SHORT),
        const char *index_file, *reflog_msg;
        char *nl;
        unsigned char sha1[20];
-       struct commit_list *parents = NULL, **pptr = &parents;
+       struct commit_list *parents = NULL;
        struct stat statbuf;
        struct commit *current_head = NULL;
        struct commit_extra_header *extra = NULL;
                if (parse_commit(current_head))
                        die(_("could not parse HEAD commit"));
        }
 +      verbose = -1; /* unspecified */
        argc = parse_and_validate_options(argc, argv, builtin_commit_options,
                                          builtin_commit_usage,
                                          prefix, current_head, &s);
 +      if (verbose == -1)
 +              verbose = (config_commit_verbose < 0) ? 0 : config_commit_verbose;
 +
        if (dry_run)
                return dry_run_commit(argc, argv, prefix, current_head, &s);
        index_file = prepare_index(argc, argv, prefix, current_head, 0);
                if (!reflog_msg)
                        reflog_msg = "commit (initial)";
        } else if (amend) {
-               struct commit_list *c;
                if (!reflog_msg)
                        reflog_msg = "commit (amend)";
-               for (c = current_head->parents; c; c = c->next)
-                       pptr = &commit_list_insert(c->item, pptr)->next;
+               parents = copy_commit_list(current_head->parents);
        } else if (whence == FROM_MERGE) {
                struct strbuf m = STRBUF_INIT;
                FILE *fp;
                int allow_fast_forward = 1;
+               struct commit_list **pptr = &parents;
  
                if (!reflog_msg)
                        reflog_msg = "commit (merge)";
-               pptr = &commit_list_insert(current_head, pptr)->next;
+               pptr = commit_list_append(current_head, pptr);
                fp = fopen(git_path_merge_head(), "r");
                if (fp == NULL)
                        die_errno(_("could not open '%s' for reading"),
                        parent = get_merge_parent(m.buf);
                        if (!parent)
                                die(_("Corrupt MERGE_HEAD file (%s)"), m.buf);
-                       pptr = &commit_list_insert(parent, pptr)->next;
+                       pptr = commit_list_append(parent, pptr);
                }
                fclose(fp);
                strbuf_release(&m);
                        reflog_msg = (whence == FROM_CHERRY_PICK)
                                        ? "commit (cherry-pick)"
                                        : "commit";
-               pptr = &commit_list_insert(current_head, pptr)->next;
+               commit_list_insert(current_head, &parents);
        }
  
        /* Finally, get the commit message */
        strbuf_reset(&sb);
 -      if (strbuf_read_file(&sb, git_path(commit_editmsg), 0) < 0) {
 +      if (strbuf_read_file(&sb, git_path_commit_editmsg(), 0) < 0) {
                int saved_errno = errno;
                rollback_index_files();
                die(_("could not read commit message: %s"), strerror(saved_errno));