OSDN Git Service

Merge branch 'ma/pager-per-subcommand-action' into maint
authorJunio C Hamano <gitster@pobox.com>
Sun, 10 Sep 2017 08:02:48 +0000 (17:02 +0900)
committerJunio C Hamano <gitster@pobox.com>
Sun, 10 Sep 2017 08:02:48 +0000 (17:02 +0900)
The "tag.pager" configuration variable was useless for those who
actually create tag objects, as it interfered with the use of an
editor.  A new mechanism has been introduced for commands to enable
pager depending on what operation is being carried out to fix this,
and then "git tag -l" is made to run pager by default.

If this works out OK, I think there are low-hanging fruits in
other commands like "git branch" that outputs long list in one mode
while taking input in another.

* ma/pager-per-subcommand-action:
  git.c: ignore pager.* when launching builtin as dashed external
  tag: change default of `pager.tag` to "on"
  tag: respect `pager.tag` in list-mode only
  t7006: add tests for how git tag paginates
  git.c: provide setup_auto_pager()
  git.c: let builtins opt for handling `pager.foo` themselves
  builtin.h: take over documentation from api-builtin.txt

1  2 
builtin/tag.c

diff --combined builtin/tag.c
@@@ -32,8 -32,7 +32,8 @@@ static const char * const git_tag_usage
  static unsigned int colopts;
  static int force_sign_annotate;
  
 -static int list_tags(struct ref_filter *filter, struct ref_sorting *sorting, const char *format)
 +static int list_tags(struct ref_filter *filter, struct ref_sorting *sorting,
 +                   struct ref_format *format)
  {
        struct ref_array array;
        char *to_free = NULL;
        if (filter->lines == -1)
                filter->lines = 0;
  
 -      if (!format) {
 +      if (!format->format) {
                if (filter->lines) {
                        to_free = xstrfmt("%s %%(contents:lines=%d)",
                                          "%(align:15)%(refname:lstrip=2)%(end)",
                                          filter->lines);
 -                      format = to_free;
 +                      format->format = to_free;
                } else
 -                      format = "%(refname:lstrip=2)";
 +                      format->format = "%(refname:lstrip=2)";
        }
  
 -      verify_ref_format(format);
 +      if (verify_ref_format(format))
 +              die(_("unable to parse format string"));
        filter->with_commit_tag_algo = 1;
        filter_refs(&array, filter, FILTER_REFS_TAGS);
        ref_array_sort(sorting, &array);
  
        for (i = 0; i < array.nr; i++)
 -              show_ref_array_item(array.items[i], format, 0);
 +              show_ref_array_item(array.items[i], format);
        ref_array_clear(&array);
        free(to_free);
  
@@@ -107,17 -105,17 +107,17 @@@ static int verify_tag(const char *name
                      const struct object_id *oid, const void *cb_data)
  {
        int flags;
 -      const char *fmt_pretty = cb_data;
 +      const struct ref_format *format = cb_data;
        flags = GPG_VERIFY_VERBOSE;
  
 -      if (fmt_pretty)
 +      if (format->format)
                flags = GPG_VERIFY_OMIT_STATUS;
  
        if (gpg_verify_tag(oid->hash, name, flags))
                return -1;
  
 -      if (fmt_pretty)
 -              pretty_print_ref(name, oid->hash, fmt_pretty);
 +      if (format->format)
 +              pretty_print_ref(name, oid->hash, format);
  
        return 0;
  }
@@@ -136,6 -134,30 +136,6 @@@ static const char tag_template_nocleanu
        "Lines starting with '%c' will be kept; you may remove them"
        " yourself if you want to.\n");
  
 -/* Parse arg given and add it the ref_sorting array */
 -static int parse_sorting_string(const char *arg, struct ref_sorting **sorting_tail)
 -{
 -      struct ref_sorting *s;
 -      int len;
 -
 -      s = xcalloc(1, sizeof(*s));
 -      s->next = *sorting_tail;
 -      *sorting_tail = s;
 -
 -      if (*arg == '-') {
 -              s->reverse = 1;
 -              arg++;
 -      }
 -      if (skip_prefix(arg, "version:", &arg) ||
 -          skip_prefix(arg, "v:", &arg))
 -              s->version = 1;
 -
 -      len = strlen(arg);
 -      s->atom = parse_ref_filter_atom(arg, arg+len);
 -
 -      return 0;
 -}
 -
  static int git_tag_config(const char *var, const char *value, void *cb)
  {
        int status;
        if (!strcmp(var, "tag.sort")) {
                if (!value)
                        return config_error_nonbool(var);
 -              parse_sorting_string(value, sorting_tail);
 +              parse_ref_sorting(sorting_tail, value);
                return 0;
        }
  
@@@ -370,7 -392,7 +370,7 @@@ int cmd_tag(int argc, const char **argv
        struct strbuf err = STRBUF_INIT;
        struct ref_filter filter;
        static struct ref_sorting *sorting = NULL, **sorting_tail = &sorting;
 -      const char *format = NULL;
 +      struct ref_format format = REF_FORMAT_INIT;
        int icase = 0;
        struct option options[] = {
                OPT_CMDMODE('l', "list", &cmdmode, N_("list tag names"), 'l'),
                        N_("print only tags of the object"), PARSE_OPT_LASTARG_DEFAULT,
                        parse_opt_object_name, (intptr_t) "HEAD"
                },
 -              OPT_STRING(  0 , "format", &format, N_("format"), N_("format to use for the output")),
 +              OPT_STRING(  0 , "format", &format.format, N_("format"),
 +                         N_("format to use for the output")),
                OPT_BOOL('i', "ignore-case", &icase, N_("sorting and filtering are case insensitive")),
                OPT_END()
        };
                        cmdmode = 'l';
        }
  
+       if (cmdmode == 'l')
+               setup_auto_pager("tag", 1);
        if ((create_tag_object || force) && (cmdmode != 0))
                usage_with_options(git_tag_usage, options);
  
                        run_column_filter(colopts, &copts);
                }
                filter.name_patterns = argv;
 -              ret = list_tags(&filter, sorting, format);
 +              ret = list_tags(&filter, sorting, &format);
                if (column_active(colopts))
                        stop_column_filter();
                return ret;
        if (cmdmode == 'd')
                return for_each_tag_name(argv, delete_tag, NULL);
        if (cmdmode == 'v') {
 -              if (format)
 -                      verify_ref_format(format);
 -              return for_each_tag_name(argv, verify_tag, format);
 +              if (format.format && verify_ref_format(&format))
 +                      usage_with_options(git_tag_usage, options);
 +              return for_each_tag_name(argv, verify_tag, &format);
        }
  
        if (msg.given || msgfile) {