зеркало из https://github.com/microsoft/git.git
Relative timestamps in git log
I noticed that I was looking at the kernel gitweb output at some point rather than just do "git log", simply because I liked seeing the simplified date-format, ie the "5 days ago" rather than a full date. This adds infrastructure to do that for "git log" too. It does NOT add the actual flag to enable it, though, so right now this patch is a no-op, but it should now be easy to add a command line flag (and possibly a config file option) to just turn on the "relative" date format. The exact cut-off points when it switches from days to weeks etc are totally arbitrary, but are picked somewhat to avoid the "1 weeks ago" thing (by making it show "10 days ago" rather than "1 week", or "70 minutes ago" rather than "1 hour ago"). [jc: with minor fix and tweak around "month" and "week" area.] Signed-off-by: Linus Torvalds <torvalds@osdl.org> Signed-off-by: Junio C Hamano <junkio@cox.net>
This commit is contained in:
Родитель
e4fbbfe9ec
Коммит
9a8e35e987
|
@ -54,7 +54,7 @@ static void pprint_tag(const unsigned char *sha1, const char *buf, unsigned long
|
|||
write_or_die(1, tagger, sp - tagger);
|
||||
date = strtoul(sp, &ep, 10);
|
||||
tz = strtol(ep, NULL, 10);
|
||||
sp = show_date(date, tz);
|
||||
sp = show_date(date, tz, 0);
|
||||
write_or_die(1, sp, strlen(sp));
|
||||
xwrite(1, "\n", 1);
|
||||
break;
|
||||
|
|
2
cache.h
2
cache.h
|
@ -286,7 +286,7 @@ extern void *read_object_with_reference(const unsigned char *sha1,
|
|||
unsigned long *size,
|
||||
unsigned char *sha1_ret);
|
||||
|
||||
const char *show_date(unsigned long time, int timezone);
|
||||
const char *show_date(unsigned long time, int timezone, int relative);
|
||||
const char *show_rfc2822_date(unsigned long time, int timezone);
|
||||
int parse_date(const char *date, char *buf, int bufsize);
|
||||
void datestamp(char *buf, int bufsize);
|
||||
|
|
4
commit.c
4
commit.c
|
@ -507,14 +507,14 @@ static int add_user_info(const char *what, enum cmit_fmt fmt, char *buf, const c
|
|||
}
|
||||
switch (fmt) {
|
||||
case CMIT_FMT_MEDIUM:
|
||||
ret += sprintf(buf + ret, "Date: %s\n", show_date(time, tz));
|
||||
ret += sprintf(buf + ret, "Date: %s\n", show_date(time, tz, 0));
|
||||
break;
|
||||
case CMIT_FMT_EMAIL:
|
||||
ret += sprintf(buf + ret, "Date: %s\n",
|
||||
show_rfc2822_date(time, tz));
|
||||
break;
|
||||
case CMIT_FMT_FULLER:
|
||||
ret += sprintf(buf + ret, "%sDate: %s\n", what, show_date(time, tz));
|
||||
ret += sprintf(buf + ret, "%sDate: %s\n", what, show_date(time, tz, 0));
|
||||
break;
|
||||
default:
|
||||
/* notin' */
|
||||
|
|
63
date.c
63
date.c
|
@ -37,6 +37,16 @@ static const char *weekday_names[] = {
|
|||
"Sundays", "Mondays", "Tuesdays", "Wednesdays", "Thursdays", "Fridays", "Saturdays"
|
||||
};
|
||||
|
||||
static time_t gm_time_t(unsigned long time, int tz)
|
||||
{
|
||||
int minutes;
|
||||
|
||||
minutes = tz < 0 ? -tz : tz;
|
||||
minutes = (minutes / 100)*60 + (minutes % 100);
|
||||
minutes = tz < 0 ? -minutes : minutes;
|
||||
return time + minutes * 60;
|
||||
}
|
||||
|
||||
/*
|
||||
* The "tz" thing is passed in as this strange "decimal parse of tz"
|
||||
* thing, which means that tz -0100 is passed in as the integer -100,
|
||||
|
@ -44,21 +54,58 @@ static const char *weekday_names[] = {
|
|||
*/
|
||||
static struct tm *time_to_tm(unsigned long time, int tz)
|
||||
{
|
||||
time_t t;
|
||||
int minutes;
|
||||
|
||||
minutes = tz < 0 ? -tz : tz;
|
||||
minutes = (minutes / 100)*60 + (minutes % 100);
|
||||
minutes = tz < 0 ? -minutes : minutes;
|
||||
t = time + minutes * 60;
|
||||
time_t t = gm_time_t(time, tz);
|
||||
return gmtime(&t);
|
||||
}
|
||||
|
||||
const char *show_date(unsigned long time, int tz)
|
||||
const char *show_date(unsigned long time, int tz, int relative)
|
||||
{
|
||||
struct tm *tm;
|
||||
static char timebuf[200];
|
||||
|
||||
if (relative) {
|
||||
unsigned long diff;
|
||||
time_t t = gm_time_t(time, tz);
|
||||
struct timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
if (now.tv_sec < t)
|
||||
return "in the future";
|
||||
diff = now.tv_sec - t;
|
||||
if (diff < 90) {
|
||||
snprintf(timebuf, sizeof(timebuf), "%lu seconds ago", diff);
|
||||
return timebuf;
|
||||
}
|
||||
/* Turn it into minutes */
|
||||
diff = (diff + 30) / 60;
|
||||
if (diff < 90) {
|
||||
snprintf(timebuf, sizeof(timebuf), "%lu minutes ago", diff);
|
||||
return timebuf;
|
||||
}
|
||||
/* Turn it into hours */
|
||||
diff = (diff + 30) / 60;
|
||||
if (diff < 36) {
|
||||
snprintf(timebuf, sizeof(timebuf), "%lu hours ago", diff);
|
||||
return timebuf;
|
||||
}
|
||||
/* We deal with number of days from here on */
|
||||
diff = (diff + 12) / 24;
|
||||
if (diff < 14) {
|
||||
snprintf(timebuf, sizeof(timebuf), "%lu days ago", diff);
|
||||
return timebuf;
|
||||
}
|
||||
/* Say weeks for the past 10 weeks or so */
|
||||
if (diff < 70) {
|
||||
snprintf(timebuf, sizeof(timebuf), "%lu weeks ago", (diff + 3) / 7);
|
||||
return timebuf;
|
||||
}
|
||||
/* Say months for the past 12 months or so */
|
||||
if (diff < 360) {
|
||||
snprintf(timebuf, sizeof(timebuf), "%lu months ago", (diff + 15) / 30);
|
||||
return timebuf;
|
||||
}
|
||||
/* Else fall back on absolute format.. */
|
||||
}
|
||||
|
||||
tm = time_to_tm(time, tz);
|
||||
if (!tm)
|
||||
return NULL;
|
||||
|
|
Загрузка…
Ссылка в новой задаче