Code

Merge branch 'nd/maint-refname-in-hierarchy-check'
authorJunio C Hamano <gitster@pobox.com>
Sun, 29 Jan 2012 21:18:51 +0000 (13:18 -0800)
committerJunio C Hamano <gitster@pobox.com>
Sun, 29 Jan 2012 21:18:51 +0000 (13:18 -0800)
* nd/maint-refname-in-hierarchy-check:
  Fix incorrect ref namespace check

1  2 
builtin/fetch.c
builtin/remote.c
log-tree.c

diff --combined builtin/fetch.c
index 0481c169ca5efd71b1b54133c69809507cb3623a,ea45cb0e8ed2b1b27ed709182ea9bcd271c91dae..ab186332fa881e0f823b0042f2d650fda8f365a8
@@@ -377,7 -377,6 +377,7 @@@ static int store_updated_refs(const cha
        const char *what, *kind;
        struct ref *rm;
        char *url, *filename = dry_run ? "/dev/null" : git_path("FETCH_HEAD");
 +      int want_merge;
  
        fp = fopen(filename, "a");
        if (!fp)
                goto abort;
        }
  
 -      for (rm = ref_map; rm; rm = rm->next) {
 -              struct ref *ref = NULL;
 -
 -              if (rm->peer_ref) {
 -                      ref = xcalloc(1, sizeof(*ref) + strlen(rm->peer_ref->name) + 1);
 -                      strcpy(ref->name, rm->peer_ref->name);
 -                      hashcpy(ref->old_sha1, rm->peer_ref->old_sha1);
 -                      hashcpy(ref->new_sha1, rm->old_sha1);
 -                      ref->force = rm->peer_ref->force;
 -              }
 +      /*
 +       * The first pass writes objects to be merged and then the
 +       * second pass writes the rest, in order to allow using
 +       * FETCH_HEAD as a refname to refer to the ref to be merged.
 +       */
 +      for (want_merge = 1; 0 <= want_merge; want_merge--) {
 +              for (rm = ref_map; rm; rm = rm->next) {
 +                      struct ref *ref = NULL;
 +
 +                      commit = lookup_commit_reference_gently(rm->old_sha1, 1);
 +                      if (!commit)
 +                              rm->merge = 0;
 +
 +                      if (rm->merge != want_merge)
 +                              continue;
 +
 +                      if (rm->peer_ref) {
 +                              ref = xcalloc(1, sizeof(*ref) + strlen(rm->peer_ref->name) + 1);
 +                              strcpy(ref->name, rm->peer_ref->name);
 +                              hashcpy(ref->old_sha1, rm->peer_ref->old_sha1);
 +                              hashcpy(ref->new_sha1, rm->old_sha1);
 +                              ref->force = rm->peer_ref->force;
 +                      }
  
 -              commit = lookup_commit_reference_gently(rm->old_sha1, 1);
 -              if (!commit)
 -                      rm->merge = 0;
  
 -              if (!strcmp(rm->name, "HEAD")) {
 -                      kind = "";
 -                      what = "";
 -              }
 -              else if (!prefixcmp(rm->name, "refs/heads/")) {
 -                      kind = "branch";
 -                      what = rm->name + 11;
 -              }
 -              else if (!prefixcmp(rm->name, "refs/tags/")) {
 -                      kind = "tag";
 -                      what = rm->name + 10;
 -              }
 -              else if (!prefixcmp(rm->name, "refs/remotes/")) {
 -                      kind = "remote-tracking branch";
 -                      what = rm->name + 13;
 -              }
 -              else {
 -                      kind = "";
 -                      what = rm->name;
 -              }
 +                      if (!strcmp(rm->name, "HEAD")) {
 +                              kind = "";
 +                              what = "";
 +                      }
 +                      else if (!prefixcmp(rm->name, "refs/heads/")) {
 +                              kind = "branch";
 +                              what = rm->name + 11;
 +                      }
 +                      else if (!prefixcmp(rm->name, "refs/tags/")) {
 +                              kind = "tag";
 +                              what = rm->name + 10;
 +                      }
 +                      else if (!prefixcmp(rm->name, "refs/remotes/")) {
 +                              kind = "remote-tracking branch";
 +                              what = rm->name + 13;
 +                      }
 +                      else {
 +                              kind = "";
 +                              what = rm->name;
 +                      }
  
 -              url_len = strlen(url);
 -              for (i = url_len - 1; url[i] == '/' && 0 <= i; i--)
 -                      ;
 -              url_len = i + 1;
 -              if (4 < i && !strncmp(".git", url + i - 3, 4))
 -                      url_len = i - 3;
 -
 -              strbuf_reset(&note);
 -              if (*what) {
 -                      if (*kind)
 -                              strbuf_addf(&note, "%s ", kind);
 -                      strbuf_addf(&note, "'%s' of ", what);
 -              }
 -              fprintf(fp, "%s\t%s\t%s",
 -                      sha1_to_hex(commit ? commit->object.sha1 :
 -                                  rm->old_sha1),
 -                      rm->merge ? "" : "not-for-merge",
 -                      note.buf);
 -              for (i = 0; i < url_len; ++i)
 -                      if ('\n' == url[i])
 -                              fputs("\\n", fp);
 -                      else
 -                              fputc(url[i], fp);
 -              fputc('\n', fp);
 -
 -              strbuf_reset(&note);
 -              if (ref) {
 -                      rc |= update_local_ref(ref, what, &note);
 -                      free(ref);
 -              } else
 -                      strbuf_addf(&note, "* %-*s %-*s -> FETCH_HEAD",
 -                                  TRANSPORT_SUMMARY_WIDTH,
 -                                  *kind ? kind : "branch",
 -                                  REFCOL_WIDTH,
 -                                  *what ? what : "HEAD");
 -              if (note.len) {
 -                      if (verbosity >= 0 && !shown_url) {
 -                              fprintf(stderr, _("From %.*s\n"),
 -                                              url_len, url);
 -                              shown_url = 1;
 +                      url_len = strlen(url);
 +                      for (i = url_len - 1; url[i] == '/' && 0 <= i; i--)
 +                              ;
 +                      url_len = i + 1;
 +                      if (4 < i && !strncmp(".git", url + i - 3, 4))
 +                              url_len = i - 3;
 +
 +                      strbuf_reset(&note);
 +                      if (*what) {
 +                              if (*kind)
 +                                      strbuf_addf(&note, "%s ", kind);
 +                              strbuf_addf(&note, "'%s' of ", what);
 +                      }
 +                      fprintf(fp, "%s\t%s\t%s",
 +                              sha1_to_hex(rm->old_sha1),
 +                              rm->merge ? "" : "not-for-merge",
 +                              note.buf);
 +                      for (i = 0; i < url_len; ++i)
 +                              if ('\n' == url[i])
 +                                      fputs("\\n", fp);
 +                              else
 +                                      fputc(url[i], fp);
 +                      fputc('\n', fp);
 +
 +                      strbuf_reset(&note);
 +                      if (ref) {
 +                              rc |= update_local_ref(ref, what, &note);
 +                              free(ref);
 +                      } else
 +                              strbuf_addf(&note, "* %-*s %-*s -> FETCH_HEAD",
 +                                          TRANSPORT_SUMMARY_WIDTH,
 +                                          *kind ? kind : "branch",
 +                                          REFCOL_WIDTH,
 +                                          *what ? what : "HEAD");
 +                      if (note.len) {
 +                              if (verbosity >= 0 && !shown_url) {
 +                                      fprintf(stderr, _("From %.*s\n"),
 +                                                      url_len, url);
 +                                      shown_url = 1;
 +                              }
 +                              if (verbosity >= 0)
 +                                      fprintf(stderr, " %s\n", note.buf);
                        }
 -                      if (verbosity >= 0)
 -                              fprintf(stderr, " %s\n", note.buf);
                }
        }
  
@@@ -585,7 -574,7 +585,7 @@@ static void find_non_local_tags(struct 
  
        for_each_ref(add_existing, &existing_refs);
        for (ref = transport_get_remote_refs(transport); ref; ref = ref->next) {
-               if (prefixcmp(ref->name, "refs/tags"))
+               if (prefixcmp(ref->name, "refs/tags/"))
                        continue;
  
                /*
diff --combined builtin/remote.c
index 583eec90e0b69a4d47a819e70352d250bae3bcef,164626b1d1a82a4b01c2c5ea58e7ac3ed49a8c17..f54a89adc795fe86f76d60cff4de9487bc792bd3
@@@ -343,7 -343,8 +343,7 @@@ static int get_ref_states(const struct 
        states->tracked.strdup_strings = 1;
        states->stale.strdup_strings = 1;
        for (ref = fetch_map; ref; ref = ref->next) {
 -              unsigned char sha1[20];
 -              if (!ref->peer_ref || read_ref(ref->peer_ref->name, sha1))
 +              if (!ref->peer_ref || !ref_exists(ref->peer_ref->name))
                        string_list_append(&states->new, abbrev_branch(ref->name));
                else
                        string_list_append(&states->tracked, abbrev_branch(ref->name));
@@@ -534,7 -535,7 +534,7 @@@ static int add_branch_for_removal(cons
        }
  
        /* don't delete non-remote-tracking refs */
-       if (prefixcmp(refname, "refs/remotes")) {
+       if (prefixcmp(refname, "refs/remotes/")) {
                /* advise user how to delete local branches */
                if (!prefixcmp(refname, "refs/heads/"))
                        string_list_append(branches->skipped,
@@@ -573,7 -574,7 +573,7 @@@ static int read_remote_branches(const c
        strbuf_addf(&buf, "refs/remotes/%s/", rename->old);
        if (!prefixcmp(refname, buf.buf)) {
                item = string_list_append(rename->remote_branches, xstrdup(refname));
 -              symref = resolve_ref(refname, orig_sha1, 1, &flag);
 +              symref = resolve_ref_unsafe(refname, orig_sha1, 1, &flag);
                if (flag & REF_ISSYMREF)
                        item->util = xstrdup(symref);
                else
@@@ -709,7 -710,7 +709,7 @@@ static int mv(int argc, const char **ar
                int flag = 0;
                unsigned char sha1[20];
  
 -              resolve_ref(item->string, sha1, 1, &flag);
 +              read_ref_full(item->string, sha1, 1, &flag);
                if (!(flag & REF_ISSYMREF))
                        continue;
                if (delete_ref(item->string, NULL, REF_NODEREF))
@@@ -1219,9 -1220,10 +1219,9 @@@ static int set_head(int argc, const cha
                usage_with_options(builtin_remote_sethead_usage, options);
  
        if (head_name) {
 -              unsigned char sha1[20];
                strbuf_addf(&buf2, "refs/remotes/%s/%s", argv[0], head_name);
                /* make sure it's valid */
 -              if (!resolve_ref(buf2.buf, sha1, 1, NULL))
 +              if (!ref_exists(buf2.buf))
                        result |= error("Not a valid ref: %s", buf2.buf);
                else if (create_symref(buf.buf, buf2.buf, "remote set-head"))
                        result |= error("Could not setup %s", buf.buf);
diff --combined log-tree.c
index c719a6e38597130597083666e5328517b075228e,21ac9047c0a9fd635e2257792eef64b6e580da27..cea8756866e5ab86f09f3fadb0fe33e92b04b4bd
@@@ -8,7 -8,6 +8,7 @@@
  #include "refs.h"
  #include "string-list.h"
  #include "color.h"
 +#include "gpg-interface.h"
  
  struct decoration name_decoration = { "object names" };
  
@@@ -120,9 -119,9 +120,9 @@@ static int add_ref_decoration(const cha
                type = DECORATION_REF_REMOTE;
        else if (!prefixcmp(refname, "refs/tags/"))
                type = DECORATION_REF_TAG;
-       else if (!prefixcmp(refname, "refs/stash"))
+       else if (!strcmp(refname, "refs/stash"))
                type = DECORATION_REF_STASH;
-       else if (!prefixcmp(refname, "HEAD"))
+       else if (!strcmp(refname, "HEAD"))
                type = DECORATION_REF_HEAD;
  
        if (!cb_data || *(int *)cb_data == DECORATE_SHORT_REFS)
@@@ -404,129 -403,6 +404,129 @@@ void log_write_email_headers(struct rev
        *extra_headers_p = extra_headers;
  }
  
 +static void show_sig_lines(struct rev_info *opt, int status, const char *bol)
 +{
 +      const char *color, *reset, *eol;
 +
 +      color = diff_get_color_opt(&opt->diffopt,
 +                                 status ? DIFF_WHITESPACE : DIFF_FRAGINFO);
 +      reset = diff_get_color_opt(&opt->diffopt, DIFF_RESET);
 +      while (*bol) {
 +              eol = strchrnul(bol, '\n');
 +              printf("%s%.*s%s%s", color, (int)(eol - bol), bol, reset,
 +                     *eol ? "\n" : "");
 +              bol = (*eol) ? (eol + 1) : eol;
 +      }
 +}
 +
 +static void show_signature(struct rev_info *opt, struct commit *commit)
 +{
 +      struct strbuf payload = STRBUF_INIT;
 +      struct strbuf signature = STRBUF_INIT;
 +      struct strbuf gpg_output = STRBUF_INIT;
 +      int status;
 +
 +      if (parse_signed_commit(commit->object.sha1, &payload, &signature) <= 0)
 +              goto out;
 +
 +      status = verify_signed_buffer(payload.buf, payload.len,
 +                                    signature.buf, signature.len,
 +                                    &gpg_output);
 +      if (status && !gpg_output.len)
 +              strbuf_addstr(&gpg_output, "No signature\n");
 +
 +      show_sig_lines(opt, status, gpg_output.buf);
 +
 + out:
 +      strbuf_release(&gpg_output);
 +      strbuf_release(&payload);
 +      strbuf_release(&signature);
 +}
 +
 +static int which_parent(const unsigned char *sha1, const struct commit *commit)
 +{
 +      int nth;
 +      const struct commit_list *parent;
 +
 +      for (nth = 0, parent = commit->parents; parent; parent = parent->next) {
 +              if (!hashcmp(parent->item->object.sha1, sha1))
 +                      return nth;
 +              nth++;
 +      }
 +      return -1;
 +}
 +
 +static int is_common_merge(const struct commit *commit)
 +{
 +      return (commit->parents
 +              && commit->parents->next
 +              && !commit->parents->next->next);
 +}
 +
 +static void show_one_mergetag(struct rev_info *opt,
 +                            struct commit_extra_header *extra,
 +                            struct commit *commit)
 +{
 +      unsigned char sha1[20];
 +      struct tag *tag;
 +      struct strbuf verify_message;
 +      int status, nth;
 +      size_t payload_size, gpg_message_offset;
 +
 +      hash_sha1_file(extra->value, extra->len, typename(OBJ_TAG), sha1);
 +      tag = lookup_tag(sha1);
 +      if (!tag)
 +              return; /* error message already given */
 +
 +      strbuf_init(&verify_message, 256);
 +      if (parse_tag_buffer(tag, extra->value, extra->len))
 +              strbuf_addstr(&verify_message, "malformed mergetag\n");
 +      else if (is_common_merge(commit) &&
 +               !hashcmp(tag->tagged->sha1,
 +                        commit->parents->next->item->object.sha1))
 +              strbuf_addf(&verify_message,
 +                          "merged tag '%s'\n", tag->tag);
 +      else if ((nth = which_parent(tag->tagged->sha1, commit)) < 0)
 +              strbuf_addf(&verify_message, "tag %s names a non-parent %s\n",
 +                                  tag->tag, tag->tagged->sha1);
 +      else
 +              strbuf_addf(&verify_message,
 +                          "parent #%d, tagged '%s'\n", nth + 1, tag->tag);
 +      gpg_message_offset = verify_message.len;
 +
 +      payload_size = parse_signature(extra->value, extra->len);
 +      if ((extra->len <= payload_size) ||
 +          (verify_signed_buffer(extra->value, payload_size,
 +                                extra->value + payload_size,
 +                                extra->len - payload_size,
 +                                &verify_message) &&
 +           verify_message.len <= gpg_message_offset)) {
 +              strbuf_addstr(&verify_message, "No signature\n");
 +              status = -1;
 +      }
 +      else if (strstr(verify_message.buf + gpg_message_offset,
 +                      ": Good signature from "))
 +              status = 0;
 +      else
 +              status = -1;
 +
 +      show_sig_lines(opt, status, verify_message.buf);
 +      strbuf_release(&verify_message);
 +}
 +
 +static void show_mergetag(struct rev_info *opt, struct commit *commit)
 +{
 +      struct commit_extra_header *extra, *to_free;
 +
 +      to_free = read_commit_extra_headers(commit, NULL);
 +      for (extra = to_free; extra; extra = extra->next) {
 +              if (strcmp(extra->key, "mergetag"))
 +                      continue; /* not a merge tag */
 +              show_one_mergetag(opt, extra, commit);
 +      }
 +      free_commit_extra_headers(to_free);
 +}
 +
  void show_log(struct rev_info *opt)
  {
        struct strbuf msgbuf = STRBUF_INIT;
                }
        }
  
 +      if (opt->show_signature) {
 +              show_signature(opt, commit);
 +              show_mergetag(opt, commit);
 +      }
 +
        if (!commit->buffer)
                return;
  
@@@ -728,7 -599,9 +728,7 @@@ int log_tree_diff_flush(struct rev_inf
  
  static int do_diff_combined(struct rev_info *opt, struct commit *commit)
  {
 -      unsigned const char *sha1 = commit->object.sha1;
 -
 -      diff_tree_combined_merge(sha1, opt->dense_combined_merges, opt);
 +      diff_tree_combined_merge(commit, opt->dense_combined_merges, opt);
        return !opt->loginfo;
  }