]> git.ipfire.org Git - thirdparty/git.git/commitdiff
pretty: provide a strict ISO 8601 date format
authorBeat Bolli <bbolli@ewanet.ch>
Fri, 29 Aug 2014 16:58:42 +0000 (18:58 +0200)
committerJunio C Hamano <gitster@pobox.com>
Fri, 29 Aug 2014 19:37:02 +0000 (12:37 -0700)
Git's "ISO" date format does not really conform to the ISO 8601
standard due to small differences, and it cannot be parsed by ISO
8601-only parsers, e.g. those of XML toolchains.

The output from "--date=iso" deviates from ISO 8601 in these ways:

  - a space instead of the `T` date/time delimiter
  - a space between time and time zone
  - no colon between hours and minutes of the time zone

Add a strict ISO 8601 date format for displaying committer and
author dates.  Use the '%aI' and '%cI' format specifiers and add
'--date=iso-strict' or '--date=iso8601-strict' date format names.

See http://thread.gmane.org/gmane.comp.version-control.git/255879 and
http://thread.gmane.org/gmane.comp.version-control.git/52414/focus=52585
for discussion.

Signed-off-by: Beat Bolli <bbolli@ewanet.ch>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/git-rev-list.txt
Documentation/pretty-formats.txt
Documentation/rev-list-options.txt
builtin/blame.c
cache.h
date.c
pretty.c
t/t4205-log-pretty-formats.sh

index 7a1585def0ce0c0ca78a2735f619f0e8bdf3506c..fd7f8b5bc1840bc93273dd7b076d86499626912a 100644 (file)
@@ -45,7 +45,7 @@ SYNOPSIS
             [ \--regexp-ignore-case | -i ]
             [ \--extended-regexp | -E ]
             [ \--fixed-strings | -F ]
-            [ \--date=(local|relative|default|iso|rfc|short) ]
+            [ \--date=(local|relative|default|iso|iso-strict|rfc|short) ]
             [ [\--objects | \--objects-edge] [ \--unpacked ] ]
             [ \--pretty | \--header ]
             [ \--bisect ]
index 85d63532a3e165110717ca2602e9dd806f10bd9f..50a2c3058e2f8fa1fc1eb5e17fe1fa86d12931c0 100644 (file)
@@ -115,7 +115,8 @@ The placeholders are:
 - '%aD': author date, RFC2822 style
 - '%ar': author date, relative
 - '%at': author date, UNIX timestamp
-- '%ai': author date, ISO 8601 format
+- '%ai': author date, ISO 8601-like format
+- '%aI': author date, strict ISO 8601 format
 - '%cn': committer name
 - '%cN': committer name (respecting .mailmap, see
   linkgit:git-shortlog[1] or linkgit:git-blame[1])
@@ -126,7 +127,8 @@ The placeholders are:
 - '%cD': committer date, RFC2822 style
 - '%cr': committer date, relative
 - '%ct': committer date, UNIX timestamp
-- '%ci': committer date, ISO 8601 format
+- '%ci': committer date, ISO 8601-like format
+- '%cI': committer date, strict ISO 8601 format
 - '%d': ref names, like the --decorate option of linkgit:git-log[1]
 - '%e': encoding
 - '%s': subject
index deb8cca9173ccbaf8c15ade3f8b3312fb6bdcbad..5d311b8d46712ab0efb863d3ecd009386476a092 100644 (file)
@@ -677,7 +677,7 @@ include::pretty-options.txt[]
 --relative-date::
        Synonym for `--date=relative`.
 
---date=(relative|local|default|iso|rfc|short|raw)::
+--date=(relative|local|default|iso|iso-strict|rfc|short|raw)::
        Only takes effect for dates shown in human-readable format, such
        as when using `--pretty`. `log.date` config variable sets a default
        value for the log command's `--date` option.
@@ -687,7 +687,16 @@ e.g. ``2 hours ago''.
 +
 `--date=local` shows timestamps in user's local time zone.
 +
-`--date=iso` (or `--date=iso8601`) shows timestamps in ISO 8601 format.
+`--date=iso` (or `--date=iso8601`) shows timestamps in a ISO 8601-like format.
+The differences to the strict ISO 8601 format are:
+
+       - a space instead of the `T` date/time delimiter
+       - a space between time and time zone
+       - no colon between hours and minutes of the time zone
+
++
+`--date=iso-strict` (or `--date=iso8601-strict`) shows timestamps in strict
+ISO 8601 format.
 +
 `--date=rfc` (or `--date=rfc2822`) shows timestamps in RFC 2822
 format, often found in email messages.
index 17d30d00aa3f6c4d0f62cae6603f9003dd2f2395..01349d07f2ff4f04de4c53805ac756d852b3377d 100644 (file)
@@ -2580,6 +2580,9 @@ parse_done:
        case DATE_RFC2822:
                blame_date_width = sizeof("Thu, 19 Oct 2006 16:00:04 -0700");
                break;
+       case DATE_ISO8601_STRICT:
+               blame_date_width = sizeof("2006-10-19T16:00:04-07:00");
+               break;
        case DATE_ISO8601:
                blame_date_width = sizeof("2006-10-19 16:00:04 -0700");
                break;
diff --git a/cache.h b/cache.h
index fcb511db70f7703f2b29dbc89dcf703065c823fe..fa92aaf95ce803234f5ce642d2129dd368972edb 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -1037,6 +1037,7 @@ enum date_mode {
        DATE_SHORT,
        DATE_LOCAL,
        DATE_ISO8601,
+       DATE_ISO8601_STRICT,
        DATE_RFC2822,
        DATE_RAW
 };
diff --git a/date.c b/date.c
index 782de95d90c6ac1a02ddfa0df81ca93ecdf910c4..5d73d9b7b223be54b8ad14c3c5a7eca1b501ec09 100644 (file)
--- a/date.c
+++ b/date.c
@@ -200,7 +200,16 @@ const char *show_date(unsigned long time, int tz, enum date_mode mode)
                                tm->tm_mday,
                                tm->tm_hour, tm->tm_min, tm->tm_sec,
                                tz);
-       else if (mode == DATE_RFC2822)
+       else if (mode == DATE_ISO8601_STRICT) {
+               char sign = (tz >= 0) ? '+' : '-';
+               tz = abs(tz);
+               strbuf_addf(&timebuf, "%04d-%02d-%02dT%02d:%02d:%02d%c%02d:%02d",
+                               tm->tm_year + 1900,
+                               tm->tm_mon + 1,
+                               tm->tm_mday,
+                               tm->tm_hour, tm->tm_min, tm->tm_sec,
+                               sign, tz / 100, tz % 100);
+       } else if (mode == DATE_RFC2822)
                strbuf_addf(&timebuf, "%.3s, %d %.3s %d %02d:%02d:%02d %+05d",
                        weekday_names[tm->tm_wday], tm->tm_mday,
                        month_names[tm->tm_mon], tm->tm_year + 1900,
@@ -751,6 +760,9 @@ enum date_mode parse_date_format(const char *format)
        else if (!strcmp(format, "iso8601") ||
                 !strcmp(format, "iso"))
                return DATE_ISO8601;
+       else if (!strcmp(format, "iso8601-strict") ||
+                !strcmp(format, "iso-strict"))
+               return DATE_ISO8601_STRICT;
        else if (!strcmp(format, "rfc2822") ||
                 !strcmp(format, "rfc"))
                return DATE_RFC2822;
index 3a1da6fd329efe1723bdb906a907ce4160c4633a..7dd5601e64873d71651260aa099594f47df7433d 100644 (file)
--- a/pretty.c
+++ b/pretty.c
@@ -731,9 +731,12 @@ static size_t format_person_part(struct strbuf *sb, char part,
        case 'r':       /* date, relative */
                strbuf_addstr(sb, show_ident_date(&s, DATE_RELATIVE));
                return placeholder_len;
-       case 'i':       /* date, ISO 8601 */
+       case 'i':       /* date, ISO 8601-like */
                strbuf_addstr(sb, show_ident_date(&s, DATE_ISO8601));
                return placeholder_len;
+       case 'I':       /* date, ISO 8601 strict */
+               strbuf_addstr(sb, show_ident_date(&s, DATE_ISO8601_STRICT));
+               return placeholder_len;
        }
 
 skip:
index 349c531989326eacfe1e1448bfed740d7fd4bd8e..f2f748399d4b3066ef3cf16ae28ec99e698e1d72 100755 (executable)
@@ -431,6 +431,14 @@ EOF
        test_cmp expected actual
 '
 
+# ISO strict date format
+test_expect_success 'ISO and ISO-strict date formats display the same values' '
+       git log --format=%ai%n%ci |
+       sed -e "s/ /T/; s/ //; s/..\$/:&/" >expected &&
+       git log --format=%aI%n%cI >actual &&
+       test_cmp expected actual
+'
+
 # get new digests (with no abbreviations)
 head1=$(git rev-parse --verify HEAD~0) &&
 head2=$(git rev-parse --verify HEAD~1) &&