Make git blame's date output format configurable, like git log

Add the following:

 - git config value blame.date that expects one of the git log date
   formats (e.g. relative,local,default,iso,...);

 - git blame command line option --date expects one of the git
   log date formats;

 - documentation in blame-options.txt;

 - git blame uses the appropriate date.c functions and enums to
   make sense of the date format and provide appropriate data;

git blame continues to line up the output columns by padding the date
column up to the max width of the chosen date format.

The date format for git blame without both blame.date and --date continues
to be ISO for backwards compatibility.

git annotate ignores the date format specifiers and continues to uses the
ISO format, as before.

Signed-off-by: Eugene Letuchy <eugene@facebook.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Eugene Letuchy 2009-02-20 14:51:11 -08:00 committed by Junio C Hamano
parent 2d602e9179
commit 31653c1abc
2 changed files with 59 additions and 16 deletions

View File

@ -70,6 +70,14 @@ of lines before or after the line given by <start>.
tree copy has the contents of the named file (specify tree copy has the contents of the named file (specify
`-` to make the command read from the standard input). `-` to make the command read from the standard input).
--date <format>::
The value is one of the following alternatives:
{relative,local,default,iso,rfc,short}. If --date is not
provided, the value of the blame.date config variable is
used. If the blame.date config variable is also not set, the
iso format is used. For more information, See the discussion
of the --date option at linkgit:git-log[1].
-M|<num>|:: -M|<num>|::
Detect moving lines in the file as well. When a commit Detect moving lines in the file as well. When a commit
moves a block of lines in a file (e.g. the original file moves a block of lines in a file (e.g. the original file

View File

@ -1,5 +1,5 @@
/* /*
* Pickaxe * Blame
* *
* Copyright (c) 2006, Junio C Hamano * Copyright (c) 2006, Junio C Hamano
*/ */
@ -40,6 +40,10 @@ static int reverse;
static int blank_boundary; static int blank_boundary;
static int incremental; static int incremental;
static int xdl_opts = XDF_NEED_MINIMAL; static int xdl_opts = XDF_NEED_MINIMAL;
static enum date_mode blame_date_mode = DATE_ISO8601;
static size_t blame_date_width;
static struct string_list mailmap; static struct string_list mailmap;
#ifndef DEBUG #ifndef DEBUG
@ -1507,24 +1511,20 @@ static const char *format_time(unsigned long time, const char *tz_str,
int show_raw_time) int show_raw_time)
{ {
static char time_buf[128]; static char time_buf[128];
time_t t = time; const char *time_str;
int minutes, tz; int time_len;
struct tm *tm; int tz;
if (show_raw_time) { if (show_raw_time) {
sprintf(time_buf, "%lu %s", time, tz_str); sprintf(time_buf, "%lu %s", time, tz_str);
return time_buf;
} }
else {
tz = atoi(tz_str); tz = atoi(tz_str);
minutes = tz < 0 ? -tz : tz; time_str = show_date(time, tz, blame_date_mode);
minutes = (minutes / 100)*60 + (minutes % 100); time_len = strlen(time_str);
minutes = tz < 0 ? -minutes : minutes; memcpy(time_buf, time_str, time_len);
t = time + minutes * 60; memset(time_buf + time_len, ' ', blame_date_width - time_len);
tm = gmtime(&t); }
strftime(time_buf, sizeof(time_buf), "%Y-%m-%d %H:%M:%S ", tm);
strcat(time_buf, tz_str);
return time_buf; return time_buf;
} }
@ -1975,6 +1975,12 @@ static int git_blame_config(const char *var, const char *value, void *cb)
blank_boundary = git_config_bool(var, value); blank_boundary = git_config_bool(var, value);
return 0; return 0;
} }
if (!strcmp(var, "blame.date")) {
if (!value)
return config_error_nonbool(var);
blame_date_mode = parse_date_format(value);
return 0;
}
return git_default_config(var, value, cb); return git_default_config(var, value, cb);
} }
@ -2239,6 +2245,8 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
git_config(git_blame_config, NULL); git_config(git_blame_config, NULL);
init_revisions(&revs, NULL); init_revisions(&revs, NULL);
revs.date_mode = blame_date_mode;
save_commit_buffer = 0; save_commit_buffer = 0;
dashdash_pos = 0; dashdash_pos = 0;
@ -2263,8 +2271,35 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
parse_done: parse_done:
argc = parse_options_end(&ctx); argc = parse_options_end(&ctx);
if (cmd_is_annotate) if (cmd_is_annotate) {
output_option |= OUTPUT_ANNOTATE_COMPAT; output_option |= OUTPUT_ANNOTATE_COMPAT;
blame_date_mode = DATE_ISO8601;
} else {
blame_date_mode = revs.date_mode;
}
/* The maximum width used to show the dates */
switch (blame_date_mode) {
case DATE_RFC2822:
blame_date_width = sizeof("Thu, 19 Oct 2006 16:00:04 -0700");
break;
case DATE_ISO8601:
blame_date_width = sizeof("2006-10-19 16:00:04 -0700");
break;
case DATE_RAW:
blame_date_width = sizeof("1161298804 -0700");
break;
case DATE_SHORT:
blame_date_width = sizeof("2006-10-19");
break;
case DATE_RELATIVE:
/* "normal" is used as the fallback for "relative" */
case DATE_LOCAL:
case DATE_NORMAL:
blame_date_width = sizeof("Thu Oct 19 16:00:04 2006 -0700");
break;
}
blame_date_width -= 1; /* strip the null */
if (DIFF_OPT_TST(&revs.diffopt, FIND_COPIES_HARDER)) if (DIFF_OPT_TST(&revs.diffopt, FIND_COPIES_HARDER))
opt |= (PICKAXE_BLAME_COPY | PICKAXE_BLAME_MOVE | opt |= (PICKAXE_BLAME_COPY | PICKAXE_BLAME_MOVE |