Merge branch 'jc/merge-tag-object' into maint
authorJunio C Hamano <gitster@pobox.com>
Wed, 24 Apr 2013 23:14:06 +0000 (16:14 -0700)
committerJunio C Hamano <gitster@pobox.com>
Wed, 24 Apr 2013 23:14:06 +0000 (16:14 -0700)
"git merge $(git rev-parse v1.8.2)" behaved quite differently from
"git merge v1.8.2", as if v1.8.2 were written as v1.8.2^0 and did
not pay much attention to the annotated tag payload. Make the code
notice the type of the tag object, in addition to the dwim_ref()
based classification the current code uses (i.e. the name appears in
refs/tags/) to decide when to special case merging of tags.

* jc/merge-tag-object:
t6200: test message for merging of an annotated tag
t6200: use test_config/test_unconfig
merge: a random object may not necssarily be a commit

1  2 
builtin/merge.c
diff --combined builtin/merge.c
index 7c8922c8b0b44307a0dbb43329301ad7d1654a46,990e90c9a4619c12fd386091d95c3acfcb9efa73..0d94d89e7409c625fd2a15f65205a45d4a6d2b89
@@@ -516,6 -516,19 +516,19 @@@ static void merge_name(const char *remo
                strbuf_release(&line);
                goto cleanup;
        }
+       if (remote_head->util) {
+               struct merge_remote_desc *desc;
+               desc = merge_remote_util(remote_head);
+               if (desc && desc->obj && desc->obj->type == OBJ_TAG) {
+                       strbuf_addf(msg, "%s\t\t%s '%s'\n",
+                                   sha1_to_hex(desc->obj->sha1),
+                                   typename(desc->obj->type),
+                                   remote);
+                       goto cleanup;
+               }
+       }
        strbuf_addf(msg, "%s\t\tcommit '%s'\n",
                sha1_to_hex(remote_head->object.sha1), remote);
  cleanup:
@@@ -628,6 -641,59 +641,6 @@@ static void write_tree_trivial(unsigne
                die(_("git write-tree failed to write a tree"));
  }
  
 -static const char *merge_argument(struct commit *commit)
 -{
 -      if (commit)
 -              return sha1_to_hex(commit->object.sha1);
 -      else
 -              return EMPTY_TREE_SHA1_HEX;
 -}
 -
 -int try_merge_command(const char *strategy, size_t xopts_nr,
 -                    const char **xopts, struct commit_list *common,
 -                    const char *head_arg, struct commit_list *remotes)
 -{
 -      const char **args;
 -      int i = 0, x = 0, ret;
 -      struct commit_list *j;
 -      struct strbuf buf = STRBUF_INIT;
 -
 -      args = xmalloc((4 + xopts_nr + commit_list_count(common) +
 -                      commit_list_count(remotes)) * sizeof(char *));
 -      strbuf_addf(&buf, "merge-%s", strategy);
 -      args[i++] = buf.buf;
 -      for (x = 0; x < xopts_nr; x++) {
 -              char *s = xmalloc(strlen(xopts[x])+2+1);
 -              strcpy(s, "--");
 -              strcpy(s+2, xopts[x]);
 -              args[i++] = s;
 -      }
 -      for (j = common; j; j = j->next)
 -              args[i++] = xstrdup(merge_argument(j->item));
 -      args[i++] = "--";
 -      args[i++] = head_arg;
 -      for (j = remotes; j; j = j->next)
 -              args[i++] = xstrdup(merge_argument(j->item));
 -      args[i] = NULL;
 -      ret = run_command_v_opt(args, RUN_GIT_CMD);
 -      strbuf_release(&buf);
 -      i = 1;
 -      for (x = 0; x < xopts_nr; x++)
 -              free((void *)args[i++]);
 -      for (j = common; j; j = j->next)
 -              free((void *)args[i++]);
 -      i += 2;
 -      for (j = remotes; j; j = j->next)
 -              free((void *)args[i++]);
 -      free(args);
 -      discard_cache();
 -      if (read_cache() < 0)
 -              die(_("failed to read the cache"));
 -      resolve_undo_clear();
 -
 -      return ret;
 -}
 -
  static int try_merge_strategy(const char *strategy, struct commit_list *common,
                              struct commit_list *remoteheads,
                              struct commit *head, const char *head_arg)
@@@ -709,6 -775,56 +722,6 @@@ static int count_unmerged_entries(void
        return ret;
  }
  
 -int checkout_fast_forward(const unsigned char *head, const unsigned char *remote)
 -{
 -      struct tree *trees[MAX_UNPACK_TREES];
 -      struct unpack_trees_options opts;
 -      struct tree_desc t[MAX_UNPACK_TREES];
 -      int i, fd, nr_trees = 0;
 -      struct dir_struct dir;
 -      struct lock_file *lock_file = xcalloc(1, sizeof(struct lock_file));
 -
 -      refresh_cache(REFRESH_QUIET);
 -
 -      fd = hold_locked_index(lock_file, 1);
 -
 -      memset(&trees, 0, sizeof(trees));
 -      memset(&opts, 0, sizeof(opts));
 -      memset(&t, 0, sizeof(t));
 -      if (overwrite_ignore) {
 -              memset(&dir, 0, sizeof(dir));
 -              dir.flags |= DIR_SHOW_IGNORED;
 -              setup_standard_excludes(&dir);
 -              opts.dir = &dir;
 -      }
 -
 -      opts.head_idx = 1;
 -      opts.src_index = &the_index;
 -      opts.dst_index = &the_index;
 -      opts.update = 1;
 -      opts.verbose_update = 1;
 -      opts.merge = 1;
 -      opts.fn = twoway_merge;
 -      setup_unpack_trees_porcelain(&opts, "merge");
 -
 -      trees[nr_trees] = parse_tree_indirect(head);
 -      if (!trees[nr_trees++])
 -              return -1;
 -      trees[nr_trees] = parse_tree_indirect(remote);
 -      if (!trees[nr_trees++])
 -              return -1;
 -      for (i = 0; i < nr_trees; i++) {
 -              parse_tree(trees[i]);
 -              init_tree_desc(t+i, trees[i]->buffer, trees[i]->size);
 -      }
 -      if (unpack_trees(nr_trees, t, &opts))
 -              return -1;
 -      if (write_cache(fd, active_cache, active_nr) ||
 -              commit_locked_index(lock_file))
 -              die(_("unable to write new index file"));
 -      return 0;
 -}
 -
  static void split_merge_strategies(const char *string, struct strategy **list,
                                   int *nr, int *alloc)
  {
@@@ -788,20 -904,20 +801,20 @@@ static const char merge_editor_comment[
  N_("Please enter a commit message to explain why this merge is necessary,\n"
     "especially if it merges an updated upstream into a topic branch.\n"
     "\n"
 -   "Lines starting with '#' will be ignored, and an empty message aborts\n"
 +   "Lines starting with '%c' will be ignored, and an empty message aborts\n"
     "the commit.\n");
  
  static void prepare_to_commit(struct commit_list *remoteheads)
  {
        struct strbuf msg = STRBUF_INIT;
 -      const char *comment = _(merge_editor_comment);
        strbuf_addbuf(&msg, &merge_msg);
        strbuf_addch(&msg, '\n');
        if (0 < option_edit)
 -              strbuf_add_lines(&msg, "# ", comment, strlen(comment));
 +              strbuf_commented_addf(&msg, _(merge_editor_comment), comment_line_char);
        write_merge_msg(&msg);
 -      run_hook(get_index_file(), "prepare-commit-msg",
 -               git_path("MERGE_MSG"), "merge", NULL, NULL);
 +      if (run_hook(get_index_file(), "prepare-commit-msg",
 +                   git_path("MERGE_MSG"), "merge", NULL, NULL))
 +              abort_commit(remoteheads, NULL);
        if (0 < option_edit) {
                if (launch_editor(git_path("MERGE_MSG"), NULL, NULL))
                        abort_commit(remoteheads, NULL);
@@@ -1221,7 -1337,6 +1234,7 @@@ int cmd_merge(int argc, const char **ar
                        memset(&opts, 0, sizeof(opts));
                        opts.add_title = !have_message;
                        opts.shortlog_len = shortlog_len;
 +                      opts.credit_people = (0 < option_edit);
  
                        fmt_merge_msg(&merge_names, &merge_msg, &opts);
                        if (merge_msg.len)
                }
  
                if (checkout_fast_forward(head_commit->object.sha1,
 -                                        commit->object.sha1)) {
 +                                        commit->object.sha1,
 +                                        overwrite_ignore)) {
                        ret = 1;
                        goto done;
                }