diff --git a/Documentation/rev-list-options.txt b/Documentation/rev-list-options.txt index 14c4cce60..359587c50 100644 --- a/Documentation/rev-list-options.txt +++ b/Documentation/rev-list-options.txt @@ -702,12 +702,16 @@ include::pretty-options.txt[] --date=:: 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. + value for the log command's `--date` option. By default, dates + are shown in the original time zone (either committer's or + author's). If `-local` is appended to the format (e.g., + `iso-local`), the user's local time zone is used instead. + `--date=relative` shows dates relative to the current time, -e.g. ``2 hours ago''. +e.g. ``2 hours ago''. The `-local` option cannot be used with +`--raw` or `--relative`. + -`--date=local` shows timestamps in user's local time zone. +`--date=local` is an alias for `--date=default-local`. + `--date=iso` (or `--date=iso8601`) shows timestamps in a ISO 8601-like format. The differences to the strict ISO 8601 format are: @@ -730,10 +734,15 @@ format, often found in email messages. `--date=format:...` feeds the format `...` to your system `strftime`. Use `--date=format:%c` to show the date in your system locale's preferred format. See the `strftime` manual for a complete list of -format placeholders. +format placeholders. When using `-local`, the correct syntax is +`--date=format-local:...`. + -`--date=default` shows timestamps in the original time zone -(either committer's or author's). +`--date=default` is the default format, and is similar to +`--date=rfc2822`, with a few exceptions: + + - there is no comma after the day-of-week + + - the time zone is omitted when the local time zone is used ifdef::git-rev-list[] --header:: diff --git a/builtin/blame.c b/builtin/blame.c index 7cc499dd3..cb4ab204a 100644 --- a/builtin/blame.c +++ b/builtin/blame.c @@ -2600,7 +2600,6 @@ int cmd_blame(int argc, const char **argv, const char *prefix) fewer display columns. */ blame_date_width = utf8_strwidth(_("4 years, 11 months ago")) + 1; /* add the null */ break; - case DATE_LOCAL: case DATE_NORMAL: blame_date_width = sizeof("Thu Oct 19 16:00:04 2006 -0700"); break; diff --git a/cache.h b/cache.h index 04c1907d5..ebb72568c 100644 --- a/cache.h +++ b/cache.h @@ -1110,7 +1110,6 @@ struct date_mode { DATE_NORMAL = 0, DATE_RELATIVE, DATE_SHORT, - DATE_LOCAL, DATE_ISO8601, DATE_ISO8601_STRICT, DATE_RFC2822, @@ -1118,6 +1117,7 @@ struct date_mode { DATE_RAW } type; const char *strftime_fmt; + int local; }; /* diff --git a/date.c b/date.c index 9f0a5ddf6..7c9f76998 100644 --- a/date.c +++ b/date.c @@ -166,6 +166,7 @@ struct date_mode *date_mode_from_type(enum date_mode_type type) if (type == DATE_STRFTIME) die("BUG: cannot create anonymous strftime date_mode struct"); mode.type = type; + mode.local = 0; return &mode; } @@ -174,7 +175,7 @@ const char *show_date(unsigned long time, int tz, const struct date_mode *mode) struct tm *tm; static struct strbuf timebuf = STRBUF_INIT; - if (mode->type == DATE_LOCAL) + if (mode->local) tz = local_tzoffset(time); if (mode->type == DATE_RAW) { @@ -232,7 +233,7 @@ const char *show_date(unsigned long time, int tz, const struct date_mode *mode) tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, tm->tm_year + 1900, - (mode->type == DATE_LOCAL) ? 0 : ' ', + mode->local ? 0 : ' ', tz); return timebuf.buf; } @@ -770,31 +771,50 @@ int parse_date(const char *date, struct strbuf *result) return 0; } +static enum date_mode_type parse_date_type(const char *format, const char **end) +{ + if (skip_prefix(format, "relative", end)) + return DATE_RELATIVE; + if (skip_prefix(format, "iso8601-strict", end) || + skip_prefix(format, "iso-strict", end)) + return DATE_ISO8601_STRICT; + if (skip_prefix(format, "iso8601", end) || + skip_prefix(format, "iso", end)) + return DATE_ISO8601; + if (skip_prefix(format, "rfc2822", end) || + skip_prefix(format, "rfc", end)) + return DATE_RFC2822; + if (skip_prefix(format, "short", end)) + return DATE_SHORT; + if (skip_prefix(format, "default", end)) + return DATE_NORMAL; + if (skip_prefix(format, "raw", end)) + return DATE_RAW; + if (skip_prefix(format, "format", end)) + return DATE_STRFTIME; + + die("unknown date format %s", format); +} + void parse_date_format(const char *format, struct date_mode *mode) { - if (!strcmp(format, "relative")) - mode->type = DATE_RELATIVE; - else if (!strcmp(format, "iso8601") || - !strcmp(format, "iso")) - mode->type = DATE_ISO8601; - else if (!strcmp(format, "iso8601-strict") || - !strcmp(format, "iso-strict")) - mode->type = DATE_ISO8601_STRICT; - else if (!strcmp(format, "rfc2822") || - !strcmp(format, "rfc")) - mode->type = DATE_RFC2822; - else if (!strcmp(format, "short")) - mode->type = DATE_SHORT; - else if (!strcmp(format, "local")) - mode->type = DATE_LOCAL; - else if (!strcmp(format, "default")) - mode->type = DATE_NORMAL; - else if (!strcmp(format, "raw")) - mode->type = DATE_RAW; - else if (skip_prefix(format, "format:", &format)) { - mode->type = DATE_STRFTIME; - mode->strftime_fmt = xstrdup(format); - } else + const char *p; + + /* historical alias */ + if (!strcmp(format, "local")) + format = "default-local"; + + mode->type = parse_date_type(format, &p); + mode->local = 0; + + if (skip_prefix(p, "-local", &p)) + mode->local = 1; + + if (mode->type == DATE_STRFTIME) { + if (!skip_prefix(p, ":", &p)) + die("date format missing colon separator: %s", format); + mode->strftime_fmt = xstrdup(p); + } else if (*p) die("unknown date format %s", format); }