Merge branch 'ps/contains-id-error-message' into next
authorJunio C Hamano <gitster@pobox.com>
Tue, 27 Feb 2018 19:15:17 +0000 (11:15 -0800)
committerJunio C Hamano <gitster@pobox.com>
Tue, 27 Feb 2018 19:15:17 +0000 (11:15 -0800)
"git tag --contains no-such-commit" gave a full list of options
after giving an error message.

* ps/contains-id-error-message:
ref-filter: make "--contains <id>" less chatty if <id> is invalid

1  2 
builtin/tag.c
ref-filter.c
diff --combined builtin/tag.c
index 8c493a569f75825133f611abc17ed267d2b1e08c,6be7f53ae8d75424d990e005c98fa793a5025bad..0177d9142049d9361ee8b0fe857f1b3d76ccf41a
@@@ -194,7 -194,6 +194,7 @@@ static int build_tag_object(struct strb
  
  struct create_tag_options {
        unsigned int message_given:1;
 +      unsigned int use_editor:1;
        unsigned int sign;
        enum {
                CLEANUP_NONE,
@@@ -221,11 -220,11 +221,11 @@@ static void create_tag(const struct obj
                    "tag %s\n"
                    "tagger %s\n\n",
                    oid_to_hex(object),
 -                  typename(type),
 +                  type_name(type),
                    tag,
                    git_committer_info(IDENT_STRICT));
  
 -      if (!opt->message_given) {
 +      if (!opt->message_given || opt->use_editor) {
                int fd;
  
                /* write the template message before editing: */
                if (fd < 0)
                        die_errno(_("could not create file '%s'"), path);
  
 -              if (!is_null_oid(prev)) {
 +              if (opt->message_given) {
 +                      write_or_die(fd, buf->buf, buf->len);
 +                      strbuf_reset(buf);
 +              } else if (!is_null_oid(prev)) {
                        write_tag_body(fd, prev);
                } else {
                        struct strbuf buf = STRBUF_INIT;
@@@ -376,7 -372,6 +376,7 @@@ int cmd_tag(int argc, const char **argv
        static struct ref_sorting *sorting = NULL, **sorting_tail = &sorting;
        struct ref_format format = REF_FORMAT_INIT;
        int icase = 0;
 +      int edit_flag = 0;
        struct option options[] = {
                OPT_CMDMODE('l', "list", &cmdmode, N_("list tag names"), 'l'),
                { OPTION_INTEGER, 'n', NULL, &filter.lines, N_("n"),
                OPT_CALLBACK('m', "message", &msg, N_("message"),
                             N_("tag message"), parse_msg_arg),
                OPT_FILENAME('F', "file", &msgfile, N_("read message from file")),
 +              OPT_BOOL('e', "edit", &edit_flag, N_("force edit of tag message")),
                OPT_BOOL('s', "sign", &opt.sign, N_("annotated and GPG-signed tag")),
                OPT_STRING(0, "cleanup", &cleanup_arg, N_("mode"),
                        N_("how to strip spaces and #comments from message")),
  
                OPT_GROUP(N_("Tag listing options")),
                OPT_COLUMN(0, "column", &colopts, N_("show tag list in columns")),
-               OPT_CONTAINS(&filter.with_commit, N_("print only tags that contain the commit")),
-               OPT_NO_CONTAINS(&filter.no_commit, N_("print only tags that don't contain the commit")),
-               OPT_WITH(&filter.with_commit, N_("print only tags that contain the commit")),
-               OPT_WITHOUT(&filter.no_commit, N_("print only tags that don't contain the commit")),
+               OPT_CONTAINS(&filter.with_commit_strs, N_("print only tags that contain the commit")),
+               OPT_NO_CONTAINS(&filter.no_commit_strs, N_("print only tags that don't contain the commit")),
+               OPT_WITH(&filter.with_commit_strs, N_("print only tags that contain the commit")),
+               OPT_WITHOUT(&filter.no_commit_strs, N_("print only tags that don't contain the commit")),
                OPT_MERGED(&filter, N_("print only tags that are merged")),
                OPT_NO_MERGED(&filter, N_("print only tags that are not merged")),
                OPT_CALLBACK(0 , "sort", sorting_tail, N_("key"),
        if (!cmdmode) {
                if (argc == 0)
                        cmdmode = 'l';
-               else if (filter.with_commit || filter.no_commit ||
-                        filter.points_at.nr || filter.merge_commit ||
+               else if (filter.points_at.nr || filter.merge_commit ||
+                        filter.with_commit_strs.nr || filter.no_commit_strs.nr ||
                         filter.lines != -1)
                        cmdmode = 'l';
        }
        }
        if (filter.lines != -1)
                die(_("-n option is only allowed in list mode"));
-       if (filter.with_commit)
+       if (filter.with_commit_strs.nr)
                die(_("--contains option is only allowed in list mode"));
-       if (filter.no_commit)
+       if (filter.no_commit_strs.nr)
                die(_("--no-contains option is only allowed in list mode"));
        if (filter.points_at.nr)
                die(_("--points-at option is only allowed in list mode"));
                die(_("tag '%s' already exists"), tag);
  
        opt.message_given = msg.given || msgfile;
 +      opt.use_editor = edit_flag;
  
        if (!cleanup_arg || !strcmp(cleanup_arg, "strip"))
                opt.cleanup_mode = CLEANUP_ALL;
diff --combined ref-filter.c
index 99a45beb14ea881390051a94f7254732446ace77,aa282a27f4d996ea2c6b9e7d7974314258e773a2..f375e7670a38770d5c201c54dd36da78501daa48
@@@ -529,12 -529,12 +529,12 @@@ static void end_align_handler(struct re
  
  static void align_atom_handler(struct atom_value *atomv, struct ref_formatting_state *state)
  {
 -      struct ref_formatting_stack *new;
 +      struct ref_formatting_stack *new_stack;
  
        push_stack_element(&state->stack);
 -      new = state->stack;
 -      new->at_end = end_align_handler;
 -      new->at_end_data = &atomv->atom->u.align;
 +      new_stack = state->stack;
 +      new_stack->at_end = end_align_handler;
 +      new_stack->at_end_data = &atomv->atom->u.align;
  }
  
  static void if_then_else_handler(struct ref_formatting_stack **stack)
  
  static void if_atom_handler(struct atom_value *atomv, struct ref_formatting_state *state)
  {
 -      struct ref_formatting_stack *new;
 +      struct ref_formatting_stack *new_stack;
        struct if_then_else *if_then_else = xcalloc(sizeof(struct if_then_else), 1);
  
        if_then_else->str = atomv->atom->u.if_then_else.str;
        if_then_else->cmp_status = atomv->atom->u.if_then_else.cmp_status;
  
        push_stack_element(&state->stack);
 -      new = state->stack;
 -      new->at_end = if_then_else_handler;
 -      new->at_end_data = if_then_else;
 +      new_stack = state->stack;
 +      new_stack->at_end = if_then_else_handler;
 +      new_stack->at_end_data = if_then_else;
  }
  
  static int is_empty(const char *s)
@@@ -769,7 -769,7 +769,7 @@@ static void grab_common_values(struct a
                if (deref)
                        name++;
                if (!strcmp(name, "objecttype"))
 -                      v->s = typename(obj->type);
 +                      v->s = type_name(obj->type);
                else if (!strcmp(name, "objectsize")) {
                        v->value = sz;
                        v->s = xstrfmt("%lu", sz);
@@@ -795,7 -795,7 +795,7 @@@ static void grab_tag_values(struct atom
                if (!strcmp(name, "tag"))
                        v->s = tag->tag;
                else if (!strcmp(name, "type") && tag->tagged)
 -                      v->s = typename(tag->tagged->type);
 +                      v->s = type_name(tag->tagged->type);
                else if (!strcmp(name, "object") && tag->tagged)
                        v->s = xstrdup(oid_to_hex(&tag->tagged->oid));
        }
@@@ -2000,6 -2000,25 +2000,25 @@@ static void do_merge_filter(struct ref_
        free(to_clear);
  }
  
+ int add_str_to_commit_list(struct string_list_item *item, void *commit_list)
+ {
+       struct object_id oid;
+       struct commit *commit;
+       if (get_oid(item->string, &oid)) {
+               error(_("malformed object name %s"), item->string);
+               exit(1);
+       }
+       commit = lookup_commit_reference(&oid);
+       if (!commit) {
+               error(_("no such commit %s"), item->string);
+               exit(1);
+       }
+       commit_list_insert(commit, commit_list);
+       return 0;
+ }
  /*
   * API for filtering a set of refs. Based on the type of refs the user
   * has requested, we iterate through those refs and apply filters
@@@ -2012,6 -2031,10 +2031,10 @@@ int filter_refs(struct ref_array *array
        int ret = 0;
        unsigned int broken = 0;
  
+       /* Convert string representation and add to commit list. */
+       for_each_string_list(&filter->with_commit_strs, add_str_to_commit_list, &filter->with_commit);
+       for_each_string_list(&filter->no_commit_strs, add_str_to_commit_list, &filter->no_commit);
        ref_cbdata.array = array;
        ref_cbdata.filter = filter;