compat/poll: sleep 1 millisecond to avoid busy wait
[gitweb.git] / builtin / for-each-ref.c
index bc655b50422f2ddf4440b134a8c2ea4d967e72e8..51798b48b54266fccd2f7b4687646d152ab70588 100644 (file)
@@ -92,7 +92,8 @@ static struct {
  */
 static const char **used_atom;
 static cmp_type *used_atom_type;
-static int used_atom_cnt, sort_atom_limit, need_tagged, need_symref;
+static int used_atom_cnt, need_tagged, need_symref;
+static int need_color_reset_at_eol;
 
 /*
  * Used to parse format string and sort specifiers
@@ -179,13 +180,21 @@ static const char *find_next(const char *cp)
 static int verify_format(const char *format)
 {
        const char *cp, *sp;
+       static const char color_reset[] = "color:reset";
+
+       need_color_reset_at_eol = 0;
        for (cp = format; *cp && (sp = find_next(cp)); ) {
                const char *ep = strchr(sp, ')');
+               int at;
+
                if (!ep)
                        return error("malformed format string %s", sp);
                /* sp points at "%(" and ep points at the closing ")" */
-               parse_atom(sp + 2, ep);
+               at = parse_atom(sp + 2, ep);
                cp = ep + 1;
+
+               if (!memcmp(used_atom[at], "color:", 6))
+                       need_color_reset_at_eol = !!strcmp(used_atom[at], color_reset);
        }
        return 0;
 }
@@ -208,6 +217,22 @@ static void *get_obj(const unsigned char *sha1, struct object **obj, unsigned lo
        return buf;
 }
 
+static int grab_objectname(const char *name, const unsigned char *sha1,
+                           struct atom_value *v)
+{
+       if (!strcmp(name, "objectname")) {
+               char *s = xmalloc(41);
+               strcpy(s, sha1_to_hex(sha1));
+               v->s = s;
+               return 1;
+       }
+       if (!strcmp(name, "objectname:short")) {
+               v->s = xstrdup(find_unique_abbrev(sha1, DEFAULT_ABBREV));
+               return 1;
+       }
+       return 0;
+}
+
 /* See grab_values */
 static void grab_common_values(struct atom_value *val, int deref, struct object *obj, void *buf, unsigned long sz)
 {
@@ -228,15 +253,8 @@ static void grab_common_values(struct atom_value *val, int deref, struct object
                        v->ul = sz;
                        v->s = s;
                }
-               else if (!strcmp(name, "objectname")) {
-                       char *s = xmalloc(41);
-                       strcpy(s, sha1_to_hex(obj->sha1));
-                       v->s = s;
-               }
-               else if (!strcmp(name, "objectname:short")) {
-                       v->s = xstrdup(find_unique_abbrev(obj->sha1,
-                                                         DEFAULT_ABBREV));
-               }
+               else if (deref)
+                       grab_objectname(name, obj->sha1, v);
        }
 }
 
@@ -435,7 +453,7 @@ static void grab_person(const char *who, struct atom_value *val, int deref, stru
                if (name[wholen] != 0 &&
                    strcmp(name + wholen, "name") &&
                    strcmp(name + wholen, "email") &&
-                   prefixcmp(name + wholen, "date"))
+                   !starts_with(name + wholen, "date"))
                        continue;
                if (!wholine)
                        wholine = find_wholine(who, wholen, buf, sz);
@@ -447,7 +465,7 @@ static void grab_person(const char *who, struct atom_value *val, int deref, stru
                        v->s = copy_name(wholine);
                else if (!strcmp(name + wholen, "email"))
                        v->s = copy_email(wholine);
-               else if (!prefixcmp(name + wholen, "date"))
+               else if (starts_with(name + wholen, "date"))
                        grab_date(wholine, v, name);
        }
 
@@ -469,7 +487,7 @@ static void grab_person(const char *who, struct atom_value *val, int deref, stru
                if (deref)
                        name++;
 
-               if (!prefixcmp(name, "creatordate"))
+               if (starts_with(name, "creatordate"))
                        grab_date(wholine, v, name);
                else if (!strcmp(name, "creator"))
                        v->s = copy_line(wholine);
@@ -650,13 +668,13 @@ static void populate_value(struct refinfo *ref)
                        name++;
                }
 
-               if (!prefixcmp(name, "refname"))
+               if (starts_with(name, "refname"))
                        refname = ref->refname;
-               else if (!prefixcmp(name, "symref"))
+               else if (starts_with(name, "symref"))
                        refname = ref->symref ? ref->symref : "";
-               else if (!prefixcmp(name, "upstream")) {
+               else if (starts_with(name, "upstream")) {
                        /* only local branches may have an upstream */
-                       if (prefixcmp(ref->refname, "refs/heads/"))
+                       if (!starts_with(ref->refname, "refs/heads/"))
                                continue;
                        branch = branch_get(ref->refname + 11);
 
@@ -664,7 +682,7 @@ static void populate_value(struct refinfo *ref)
                            !branch->merge[0]->dst)
                                continue;
                        refname = branch->merge[0]->dst;
-               } else if (!prefixcmp(name, "color:")) {
+               } else if (starts_with(name, "color:")) {
                        char color[COLOR_MAXLEN] = "";
 
                        color_parse(name + 6, "--format", color);
@@ -683,6 +701,8 @@ static void populate_value(struct refinfo *ref)
                                v->s = xstrdup(buf + 1);
                        }
                        continue;
+               } else if (!deref && grab_objectname(name, ref->objectname, v)) {
+                       continue;
                } else if (!strcmp(name, "HEAD")) {
                        const char *head;
                        unsigned char sha1[20];
@@ -705,7 +725,7 @@ static void populate_value(struct refinfo *ref)
                                refname = shorten_unambiguous_ref(refname,
                                                      warn_ambiguous_refs);
                        else if (!strcmp(formatp, "track") &&
-                               !prefixcmp(name, "upstream")) {
+                                starts_with(name, "upstream")) {
                                char buf[40];
 
                                stat_tracking_info(branch, &num_ours, &num_theirs);
@@ -724,7 +744,7 @@ static void populate_value(struct refinfo *ref)
                                }
                                continue;
                        } else if (!strcmp(formatp, "trackshort") &&
-                               !prefixcmp(name, "upstream")) {
+                                  starts_with(name, "upstream")) {
                                assert(branch);
                                stat_tracking_info(branch, &num_ours, &num_theirs);
                                if (!num_ours && !num_theirs)
@@ -914,11 +934,9 @@ static void sort_refs(struct ref_sort *sort, struct refinfo **refs, int num_refs
        qsort(refs, num_refs, sizeof(struct refinfo *), compare_refs);
 }
 
-static void print_value(struct refinfo *ref, int atom, int quote_style)
+static void print_value(struct atom_value *v, int quote_style)
 {
-       struct atom_value *v;
        struct strbuf sb = STRBUF_INIT;
-       get_value(ref, atom, &v);
        switch (quote_style) {
        case QUOTE_NONE:
                fputs(v->s, stdout);
@@ -985,15 +1003,26 @@ static void show_ref(struct refinfo *info, const char *format, int quote_style)
        const char *cp, *sp, *ep;
 
        for (cp = format; *cp && (sp = find_next(cp)); cp = ep + 1) {
+               struct atom_value *atomv;
+
                ep = strchr(sp, ')');
                if (cp < sp)
                        emit(cp, sp);
-               print_value(info, parse_atom(sp + 2, ep), quote_style);
+               get_value(info, parse_atom(sp + 2, ep), &atomv);
+               print_value(atomv, quote_style);
        }
        if (*cp) {
                sp = cp + strlen(cp);
                emit(cp, sp);
        }
+       if (need_color_reset_at_eol) {
+               struct atom_value resetv;
+               char color[COLOR_MAXLEN] = "";
+
+               color_parse("reset", "--format", color);
+               resetv.s = color;
+               print_value(&resetv, quote_style);
+       }
        putchar('\n');
 }
 
@@ -1076,7 +1105,6 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix)
 
        if (!sort)
                sort = default_sort();
-       sort_atom_limit = used_atom_cnt;
 
        /* for warn_ambiguous_refs */
        git_config(git_default_config, NULL);