Merge branch 'tb/ref-filter-empty-modifier'
authorJunio C Hamano <gitster@pobox.com>
Sat, 7 Oct 2017 07:27:56 +0000 (16:27 +0900)
committerJunio C Hamano <gitster@pobox.com>
Sat, 7 Oct 2017 07:27:56 +0000 (16:27 +0900)
In the "--format=..." option of the "git for-each-ref" command (and
its friends, i.e. the listing mode of "git branch/tag"), "%(atom:)"
(e.g. "%(refname:)", "%(body:)" used to error out. Instead, treat
them as if the colon and an empty string that follows it were not
there.

* tb/ref-filter-empty-modifier:
ref-filter.c: pass empty-string as NULL to atom parsers

1  2 
ref-filter.c
t/t6300-for-each-ref.sh
diff --combined ref-filter.c
index 55323620ab2aedc443989a876b4f4c43df6115cf,f3e53d4448f10ca1002e546890ca682c02ecc9ad..45a3be83402066a5bf7507dde50f0dc07efbf645
@@@ -295,7 -295,9 +295,7 @@@ static void if_atom_parser(const struc
  
  static void head_atom_parser(const struct ref_format *format, struct used_atom *atom, const char *arg)
  {
 -      struct object_id unused;
 -
 -      atom->u.head = resolve_refdup("HEAD", RESOLVE_REF_READING, unused.hash, NULL);
 +      atom->u.head = resolve_refdup("HEAD", RESOLVE_REF_READING, NULL, NULL);
  }
  
  static struct {
@@@ -413,8 -415,16 +413,16 @@@ static int parse_ref_filter_atom(const 
        REALLOC_ARRAY(used_atom, used_atom_cnt);
        used_atom[at].name = xmemdupz(atom, ep - atom);
        used_atom[at].type = valid_atom[i].cmp_type;
-       if (arg)
+       if (arg) {
                arg = used_atom[at].name + (arg - atom) + 1;
+               if (!*arg) {
+                       /*
+                        * Treat empty sub-arguments list as NULL (i.e.,
+                        * "%(atom:)" is equivalent to "%(atom)").
+                        */
+                       arg = NULL;
+               }
+       }
        memset(&used_atom[at].u, 0, sizeof(used_atom[at].u));
        if (valid_atom[i].parser)
                valid_atom[i].parser(format, &used_atom[at], arg);
@@@ -1315,8 -1325,9 +1323,8 @@@ static void populate_value(struct ref_a
        ref->value = xcalloc(used_atom_cnt, sizeof(struct atom_value));
  
        if (need_symref && (ref->flag & REF_ISSYMREF) && !ref->symref) {
 -              struct object_id unused1;
                ref->symref = resolve_refdup(ref->refname, RESOLVE_REF_READING,
 -                                           unused1.hash, NULL);
 +                                           NULL, NULL);
                if (!ref->symref)
                        ref->symref = "";
        }
diff --combined t/t6300-for-each-ref.sh
index 6358134805302583a49f5102c225b643497637de,edc1bd8eabd6df02e49646930ee5eb56bf1b77f9..a6f51a50033d1e0d25b5adb64ad38142d7f136e0
@@@ -51,6 -51,7 +51,7 @@@ test_atom() 
  }
  
  test_atom head refname refs/heads/master
+ test_atom head refname: refs/heads/master
  test_atom head refname:short master
  test_atom head refname:lstrip=1 heads/master
  test_atom head refname:lstrip=2 master
@@@ -425,7 -426,8 +426,7 @@@ test_expect_success 'set up color tests
  '
  
  test_expect_success TTY '%(color) shows color with a tty' '
 -      test_terminal env TERM=vt100 \
 -              git for-each-ref --format="$color_format" >actual.raw &&
 +      test_terminal git for-each-ref --format="$color_format" >actual.raw &&
        test_decode_color <actual.raw >actual &&
        test_cmp expected.color actual
  '
@@@ -435,8 -437,8 +436,8 @@@ test_expect_success '%(color) does not 
        test_cmp expected.bare actual
  '
  
 -test_expect_success 'color.ui=always can override tty check' '
 -      git -c color.ui=always for-each-ref --format="$color_format" >actual.raw &&
 +test_expect_success '--color can override tty check' '
 +      git for-each-ref --color --format="$color_format" >actual.raw &&
        test_decode_color <actual.raw >actual &&
        test_cmp expected.color actual
  '