Make for-each-ref's grab_date() support per-atom formatting
authorAndy Parkins <andyparkins@gmail.com>
Fri, 28 Sep 2007 14:17:45 +0000 (15:17 +0100)
committerJunio C Hamano <gitster@pobox.com>
Sun, 30 Sep 2007 03:31:59 +0000 (20:31 -0700)
grab_date() gets an extra parameter - atomname; this extra parameter is
checked to see if it has a ":<format>" extra component in it, and if so
that "<format>" string is passed to parse_date_format() to produce an
enum date_mode value which is then further passed to show_date().

In short it allows the user of git-for-each-ref to do things like this:

$ git-for-each-ref --format='%(taggerdate:default)' refs/tags/v1.5.2
Sun May 20 00:30:42 2007 -0700
$ git-for-each-ref --format='%(taggerdate:relative)' refs/tags/v1.5.2
4 months ago
$ git-for-each-ref --format='%(taggerdate:short)' refs/tags/v1.5.2
2007-05-20
$ git-for-each-ref --format='%(taggerdate:local)' refs/tags/v1.5.2
Sun May 20 08:30:42 2007
$ git-for-each-ref --format='%(taggerdate:iso8601)' refs/tags/v1.5.2
2007-05-20 00:30:42 -0700
$ git-for-each-ref --format='%(taggerdate:rfc2822)' refs/tags/v1.5.2
Sun, 20 May 2007 00:30:42 -0700

The default, when no ":<format>" is specified is ":default", leaving the
existing behaviour unchanged.

Signed-off-by: Andy Parkins <andyparkins@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/git-for-each-ref.txt
builtin-for-each-ref.c
index 6df8e8500450ad65a2de86e3daa0ab2f7692a2d2..f1f90cca62f61327a13b5ab41862596ca24a9b8f 100644 (file)
@@ -100,6 +100,11 @@ In any case, a field name that refers to a field inapplicable to
 the object referred by the ref does not cause an error.  It
 returns an empty string instead.
 
 the object referred by the ref does not cause an error.  It
 returns an empty string instead.
 
+As a special case for the date-type fields, you may specify a format for
+the date by adding one of `:default`, `:relative`, `:short`, `:local`,
+`:iso8601` or `:rfc2822` to the end of the fieldname; e.g.
+`%(taggerdate:relative)`.
+
 
 EXAMPLES
 --------
 
 EXAMPLES
 --------
index 74a7337da52ccab6eb25d51eeca4baba486a7a83..c904ac31018cc3b085367764e95dd0e17657a212 100644 (file)
@@ -356,12 +356,26 @@ static const char *copy_email(const char *buf)
        return line;
 }
 
        return line;
 }
 
-static void grab_date(const char *buf, struct atom_value *v)
+static void grab_date(const char *buf, struct atom_value *v, const char *atomname)
 {
        const char *eoemail = strstr(buf, "> ");
        char *zone;
        unsigned long timestamp;
        long tz;
 {
        const char *eoemail = strstr(buf, "> ");
        char *zone;
        unsigned long timestamp;
        long tz;
+       enum date_mode date_mode = DATE_NORMAL;
+       const char *formatp;
+
+       /*
+        * We got here because atomname ends in "date" or "date<something>";
+        * it's not possible that <something> is not ":<format>" because
+        * parse_atom() wouldn't have allowed it, so we can assume that no
+        * ":" means no format is specified, and use the default.
+        */
+       formatp = strchr(atomname, ':');
+       if (formatp != NULL) {
+               formatp++;
+               date_mode = parse_date_format(formatp);
+       }
 
        if (!eoemail)
                goto bad;
 
        if (!eoemail)
                goto bad;
@@ -371,7 +385,7 @@ static void grab_date(const char *buf, struct atom_value *v)
        tz = strtol(zone, NULL, 10);
        if ((tz == LONG_MIN || tz == LONG_MAX) && errno == ERANGE)
                goto bad;
        tz = strtol(zone, NULL, 10);
        if ((tz == LONG_MIN || tz == LONG_MAX) && errno == ERANGE)
                goto bad;
-       v->s = xstrdup(show_date(timestamp, tz, 0));
+       v->s = xstrdup(show_date(timestamp, tz, date_mode));
        v->ul = timestamp;
        return;
  bad:
        v->ul = timestamp;
        return;
  bad:
@@ -398,7 +412,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") &&
                if (name[wholen] != 0 &&
                    strcmp(name + wholen, "name") &&
                    strcmp(name + wholen, "email") &&
-                   strcmp(name + wholen, "date"))
+                   prefixcmp(name + wholen, "date"))
                        continue;
                if (!wholine)
                        wholine = find_wholine(who, wholen, buf, sz);
                        continue;
                if (!wholine)
                        wholine = find_wholine(who, wholen, buf, sz);
@@ -410,8 +424,8 @@ 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);
                        v->s = copy_name(wholine);
                else if (!strcmp(name + wholen, "email"))
                        v->s = copy_email(wholine);
-               else if (!strcmp(name + wholen, "date"))
-                       grab_date(wholine, v);
+               else if (!prefixcmp(name + wholen, "date"))
+                       grab_date(wholine, v, name);
        }
 
        /* For a tag or a commit object, if "creator" or "creatordate" is
        }
 
        /* For a tag or a commit object, if "creator" or "creatordate" is
@@ -431,8 +445,8 @@ static void grab_person(const char *who, struct atom_value *val, int deref, stru
                if (deref)
                        name++;
 
                if (deref)
                        name++;
 
-               if (!strcmp(name, "creatordate"))
-                       grab_date(wholine, v);
+               if (!prefixcmp(name, "creatordate"))
+                       grab_date(wholine, v, name);
                else if (!strcmp(name, "creator"))
                        v->s = copy_line(wholine);
        }
                else if (!strcmp(name, "creator"))
                        v->s = copy_line(wholine);
        }