Add --date={local,relative,default}
authorJunio C Hamano <junkio@cox.net>
Wed, 25 Apr 2007 06:36:22 +0000 (23:36 -0700)
committerJunio C Hamano <junkio@cox.net>
Thu, 26 Apr 2007 04:39:43 +0000 (21:39 -0700)
This adds --date={local,relative,default} option to log family of commands,
to allow displaying timestamps in user's local timezone, relative time, or
the default format.

Existing --relative-date option is a synonym of --date=relative; we could
probably deprecate it in the long run.

Signed-off-by: Junio C Hamano <junkio@cox.net>
Documentation/git-rev-list.txt
builtin-rev-list.c
cache.h
commit.c
commit.h
date.c
log-tree.c
revision.c
revision.h

index 77e068b15fb02da40a8c4c9f35d076d62f379587..1b12b4f2a45e5650be067a3b05ce56c17a5422fc 100644 (file)
@@ -25,6 +25,7 @@ SYNOPSIS
             [ \--cherry-pick ]
             [ \--encoding[=<encoding>] ]
             [ \--(author|committer|grep)=<pattern> ]
+            [ \--date={local|relative|default} ]
             [ [\--objects | \--objects-edge] [ \--unpacked ] ]
             [ \--pretty | \--header ]
             [ \--bisect ]
@@ -90,9 +91,20 @@ include::pretty-formats.txt[]
 
 --relative-date::
 
-       Show dates relative to the current time, e.g. "2 hours ago".
+       Synonym for `--date=relative`.
+
+--date={relative,local,default}::
+
        Only takes effect for dates shown in human-readable format, such
        as when using "--pretty".
++
+`--date=relative` shows dates relative to the current time,
+e.g. "2 hours ago".
++
+`--date=local` shows timestamps in user's local timezone.
++
+`--date=default` shows timestamps in the original timezone
+(either committer's or author's).
 
 --header::
 
index c0329dcecdbb4775b2c438a0bf6429a5ee72b18e..ebf53f5944f1a53c5336f69e2ef3105ce50d0823 100644 (file)
@@ -95,7 +95,7 @@ static void show_commit(struct commit *commit)
                static char pretty_header[16384];
                pretty_print_commit(revs.commit_format, commit, ~0,
                                    pretty_header, sizeof(pretty_header),
-                                   revs.abbrev, NULL, NULL, revs.relative_date);
+                                   revs.abbrev, NULL, NULL, revs.date_mode);
                printf("%s%c", pretty_header, hdr_termination);
        }
        fflush(stdout);
diff --git a/cache.h b/cache.h
index 38a0cbd580a8497b18881548f7995bcfe97666af..8e76152645dac5ab5b0b5b54a2c87aa36d51bcff 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -389,7 +389,7 @@ extern void *read_object_with_reference(const unsigned char *sha1,
                                        unsigned long *size,
                                        unsigned char *sha1_ret);
 
-enum date_mode { DATE_NORMAL = 0, DATE_RELATIVE, DATE_SHORT };
+enum date_mode { DATE_NORMAL = 0, DATE_RELATIVE, DATE_SHORT, DATE_LOCAL };
 const char *show_date(unsigned long time, int timezone, enum date_mode mode);
 const char *show_rfc2822_date(unsigned long time, int timezone);
 int parse_date(const char *date, char *buf, int bufsize);
index 10466c4ae0cb1db8648b9191fece9d9dbf238cb6..f1ba972d9abcb218b9aae0680a753edeb3666bc3 100644 (file)
--- a/commit.c
+++ b/commit.c
@@ -526,7 +526,7 @@ static int add_rfc2047(char *buf, const char *line, int len,
 }
 
 static int add_user_info(const char *what, enum cmit_fmt fmt, char *buf,
-                        const char *line, int relative_date,
+                        const char *line, enum date_mode dmode,
                         const char *encoding)
 {
        char *date;
@@ -569,7 +569,7 @@ static int add_user_info(const char *what, enum cmit_fmt fmt, char *buf,
        switch (fmt) {
        case CMIT_FMT_MEDIUM:
                ret += sprintf(buf + ret, "Date:   %s\n",
-                              show_date(time, tz, relative_date));
+                              show_date(time, tz, dmode));
                break;
        case CMIT_FMT_EMAIL:
                ret += sprintf(buf + ret, "Date: %s\n",
@@ -577,7 +577,7 @@ static int add_user_info(const char *what, enum cmit_fmt fmt, char *buf,
                break;
        case CMIT_FMT_FULLER:
                ret += sprintf(buf + ret, "%sDate: %s\n", what,
-                              show_date(time, tz, relative_date));
+                              show_date(time, tz, dmode));
                break;
        default:
                /* notin' */
@@ -919,7 +919,7 @@ unsigned long pretty_print_commit(enum cmit_fmt fmt,
                                  char *buf, unsigned long space,
                                  int abbrev, const char *subject,
                                  const char *after_subject,
-                                 int relative_date)
+                                 enum date_mode dmode)
 {
        int hdr = 1, body = 0, seen_title = 0;
        unsigned long offset = 0;
@@ -1023,14 +1023,14 @@ unsigned long pretty_print_commit(enum cmit_fmt fmt,
                                offset += add_user_info("Author", fmt,
                                                        buf + offset,
                                                        line + 7,
-                                                       relative_date,
+                                                       dmode,
                                                        encoding);
                        if (!memcmp(line, "committer ", 10) &&
                            (fmt == CMIT_FMT_FULL || fmt == CMIT_FMT_FULLER))
                                offset += add_user_info("Commit", fmt,
                                                        buf + offset,
                                                        line + 10,
-                                                       relative_date,
+                                                       dmode,
                                                        encoding);
                        continue;
                }
index 59de17eff81dc6987350baab086935de7c9dcd1f..86e8dca0c9dbac4d990d959296145805319b477a 100644 (file)
--- a/commit.h
+++ b/commit.h
@@ -61,7 +61,7 @@ enum cmit_fmt {
 };
 
 extern enum cmit_fmt get_commit_format(const char *arg);
-extern unsigned long pretty_print_commit(enum cmit_fmt fmt, const struct commit *, unsigned long len, char *buf, unsigned long space, int abbrev, const char *subject, const char *after_subject, int relative_date);
+extern unsigned long pretty_print_commit(enum cmit_fmt fmt, const struct commit *, unsigned long len, char *buf, unsigned long space, int abbrev, const char *subject, const char *after_subject, enum date_mode dmode);
 
 /** Removes the first commit from a list sorted by date, and adds all
  * of its parents.
diff --git a/date.c b/date.c
index 0ceccbe03401faa67836577b9bdbe139fe025dd5..a9b59a289e7b22f34958ccc7b80b02a01cf793c6 100644 (file)
--- a/date.c
+++ b/date.c
@@ -55,6 +55,32 @@ static struct tm *time_to_tm(unsigned long time, int tz)
        return gmtime(&t);
 }
 
+/*
+ * What value of "tz" was in effect back then at "time" in the
+ * local timezone?
+ */
+static int local_tzoffset(unsigned long time)
+{
+       time_t t, t_local;
+       struct tm tm;
+       int offset, eastwest;
+
+       t = time;
+       localtime_r(&t, &tm);
+       t_local = my_mktime(&tm);
+
+       if (t_local < t) {
+               eastwest = -1;
+               offset = t - t_local;
+       } else {
+               eastwest = 1;
+               offset = t_local - t;
+       }
+       offset /= 60; /* in minutes */
+       offset = (offset % 60) + ((offset / 60) * 100);
+       return offset * eastwest;
+}
+
 const char *show_date(unsigned long time, int tz, enum date_mode mode)
 {
        struct tm *tm;
@@ -102,6 +128,9 @@ const char *show_date(unsigned long time, int tz, enum date_mode mode)
                /* Else fall back on absolute format.. */
        }
 
+       if (mode == DATE_LOCAL)
+               tz = local_tzoffset(time);
+
        tm = time_to_tm(time, tz);
        if (!tm)
                return NULL;
@@ -109,12 +138,14 @@ const char *show_date(unsigned long time, int tz, enum date_mode mode)
                sprintf(timebuf, "%04d-%02d-%02d", tm->tm_year + 1900,
                                tm->tm_mon + 1, tm->tm_mday);
        else
-               sprintf(timebuf, "%.3s %.3s %d %02d:%02d:%02d %d %+05d",
+               sprintf(timebuf, "%.3s %.3s %d %02d:%02d:%02d %d%c%+05d",
                                weekday_names[tm->tm_wday],
                                month_names[tm->tm_mon],
                                tm->tm_mday,
                                tm->tm_hour, tm->tm_min, tm->tm_sec,
-                               tm->tm_year + 1900, tz);
+                               tm->tm_year + 1900,
+                               (mode == DATE_LOCAL) ? 0 : ' ',
+                               tz);
        return timebuf;
 }
 
index 300b73356054ffddb304c2a5cfffae680c0b5dd6..c679324c073b50a083daec568e4832e74a8bf4f3 100644 (file)
@@ -267,7 +267,7 @@ void show_log(struct rev_info *opt, const char *sep)
                if (opt->reflog_info) {
                        show_reflog_message(opt->reflog_info,
                                    opt->commit_format == CMIT_FMT_ONELINE,
-                                   opt->relative_date);
+                                   opt->date_mode);
                        if (opt->commit_format == CMIT_FMT_ONELINE) {
                                printf("%s", sep);
                                return;
@@ -280,7 +280,7 @@ void show_log(struct rev_info *opt, const char *sep)
         */
        len = pretty_print_commit(opt->commit_format, commit, ~0u, this_header,
                                  sizeof(this_header), abbrev, subject,
-                                 extra_headers, opt->relative_date);
+                                 extra_headers, opt->date_mode);
 
        if (opt->add_signoff)
                len = append_signoff(this_header, sizeof(this_header), len,
index 49bd29225bd3be8b06cf4316e06761d5d3d6c011..e60a26c6bb3f6ec77c3db30bc0b59a5a8e30e604 100644 (file)
@@ -1111,7 +1111,18 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
                                continue;
                        }
                        if (!strcmp(arg, "--relative-date")) {
-                               revs->relative_date = 1;
+                               revs->date_mode = DATE_RELATIVE;
+                               continue;
+                       }
+                       if (!strncmp(arg, "--date=", 7)) {
+                               if (!strcmp(arg + 7, "relative"))
+                                       revs->date_mode = DATE_RELATIVE;
+                               else if (!strcmp(arg + 7, "local"))
+                                       revs->date_mode = DATE_LOCAL;
+                               else if (!strcmp(arg + 7, "default"))
+                                       revs->date_mode = DATE_NORMAL;
+                               else
+                                       die("unknown date format %s", arg);
                                continue;
                        }
 
index 5b41e2da208c41ab316585b80a95e717fcbb198e..cdf94ad695a1a929ac094a9a42c868e75c1182a5 100644 (file)
@@ -63,8 +63,8 @@ struct rev_info {
 
        /* Format info */
        unsigned int    shown_one:1,
-                       abbrev_commit:1,
-                       relative_date:1;
+                       abbrev_commit:1;
+       enum date_mode date_mode;
 
        const char **ignore_packed; /* pretend objects in these are unpacked */
        int num_ignore_packed;