{"thread":{"id":"17926","subject":"[PATCH 1/2] Make git blame's date output format configurable, like git log","startedAt":"2009-02-20T22:51:11Z","lastAt":"2009-02-24T05:00:28Z","messageCount":6,"participants":["eletuchy@gmail.com","Junio C Hamano","Jeff King","Eugene Letuchy"],"isPatch":true,"patchVersion":1,"patchTotal":2},"messages":[{"id":"105663","messageId":"1235170271-10694-1-git-send-email-eletuchy@gmail.com","threadId":"17926","inReplyTo":null,"subject":"[PATCH 1/2] Make git blame's date output format configurable, like git log","fromName":"","fromEmail":"eletuchy@gmail.com","sentAt":"2009-02-20T22:51:11Z","receivedAt":"2009-02-20T22:51:11Z","isPatch":true,"sender":{"key":"eletuchy@gmail.com","avatar":null},"body":"From: Eugene Letuchy <eugene@facebook.com>\n\nAdd the following:\n - git config value blame.date that expects one of the git log date\n   formats ({relative,local,default,iso,rfc,short})\n - git blame command line option --date expects one of the git\n   log date formats ({relative,local,default,iso,rfc,short})\n - documentation in blame-options.txt\n - git blame uses the appropriate date.c functions and enums to\n   make sense of the date format and provide appropriate data\n - git blame continues to line up the output columns (by padding the\n   date column up to the max width of the chosen date format)\n - the date format for git blame without both blame.date and --date\n   continues to be ISO for backwards compatibility\n - git annotate ignores the date format specifiers and continues to\n   uses the ISO format, as before\n\nSigned-off-by: Eugene Letuchy <eugene@facebook.com>\n---\n Documentation/blame-options.txt |    8 +++++\n builtin-blame.c                 |   62 +++++++++++++++++++++++++++++----------\n 2 files changed, 54 insertions(+), 16 deletions(-)\n\ndiff --git a/Documentation/blame-options.txt b/Documentation/blame-options.txt\nindex 1ab1b96..ad00d36 100644\n--- a/Documentation/blame-options.txt\n+++ b/Documentation/blame-options.txt\n@@ -63,6 +63,14 @@ of lines before or after the line given by <start>.\n \ttree copy has the contents of the named file (specify\n \t`-` to make the command read from the standard input).\n \n+--date <format>::\n+\tThe value is one of the following alternatives:\n+\t{relative,local,default,iso,rfc,short}. If --date is not\n+\tprovided, the value of the blame.date config variable is\n+\tused. If the blame.date config variable is also not set, the\n+\tiso format is used. For more information, See the discussion\n+\tof the --date option at linkgit:git-log[1].\n+\n -M|<num>|::\n \tDetect moving lines in the file as well.  When a commit\n \tmoves a block of lines in a file (e.g. the original file\ndiff --git a/builtin-blame.c b/builtin-blame.c\nindex 114a214..aa5c66c 100644\n--- a/builtin-blame.c\n+++ b/builtin-blame.c\n@@ -1,5 +1,5 @@\n /*\n- * Pickaxe\n+ * Blame\n  *\n  * Copyright (c) 2006, Junio C Hamano\n  */\n@@ -40,6 +40,10 @@ static int reverse;\n static int blank_boundary;\n static int incremental;\n static int xdl_opts = XDF_NEED_MINIMAL;\n+\n+static enum date_mode blame_date_mode = DATE_ISO8601;\n+static size_t blame_date_width;\n+\n static struct string_list mailmap;\n \n #ifndef DEBUG\n@@ -1507,24 +1511,20 @@ static const char *format_time(unsigned long time, const char *tz_str,\n \t\t\t       int show_raw_time)\n {\n \tstatic char time_buf[128];\n-\ttime_t t = time;\n-\tint minutes, tz;\n-\tstruct tm *tm;\n+\tconst char *time_str;\n+\tint time_len;\n+\tint tz;\n \n \tif (show_raw_time) {\n \t\tsprintf(time_buf, \"%lu %s\", time, tz_str);\n-\t\treturn time_buf;\n \t}\n-\n-\ttz = atoi(tz_str);\n-\tminutes = tz < 0 ? -tz : tz;\n-\tminutes = (minutes / 100)*60 + (minutes % 100);\n-\tminutes = tz < 0 ? -minutes : minutes;\n-\tt = time + minutes * 60;\n-\ttm = gmtime(&t);\n-\n-\tstrftime(time_buf, sizeof(time_buf), \"%Y-%m-%d %H:%M:%S \", tm);\n-\tstrcat(time_buf, tz_str);\n+\telse {\n+\t\ttz = atoi(tz_str);\n+\t\ttime_str = show_date(time, tz, blame_date_mode);\n+\t\ttime_len = strlen(time_str);\n+\t\tmemcpy(time_buf, time_str, time_len);\n+\t\tmemset(time_buf + time_len, ' ', blame_date_width - time_len);\n+\t}\n \treturn time_buf;\n }\n \n@@ -1975,6 +1975,9 @@ static int git_blame_config(const char *var, const char *value, void *cb)\n \t\tblank_boundary = git_config_bool(var, value);\n \t\treturn 0;\n \t}\n+\tif (!strcmp(var, \"blame.date\") && value[0]) {\n+\t\tblame_date_mode = parse_date_format(value);\n+\t}\n \treturn git_default_config(var, value, cb);\n }\n \n@@ -2239,6 +2242,8 @@ int cmd_blame(int argc, const char **argv, const char *prefix)\n \n \tgit_config(git_blame_config, NULL);\n \tinit_revisions(&revs, NULL);\n+\trevs.date_mode = blame_date_mode;\n+\n \tsave_commit_buffer = 0;\n \tdashdash_pos = 0;\n \n@@ -2263,8 +2268,33 @@ int cmd_blame(int argc, const char **argv, const char *prefix)\n parse_done:\n \targc = parse_options_end(&ctx);\n \n-\tif (cmd_is_annotate)\n+\tif (cmd_is_annotate) {\n \t\toutput_option |= OUTPUT_ANNOTATE_COMPAT;\n+\t\tblame_date_mode = DATE_ISO8601;\n+\t} else {\n+\t\tblame_date_mode = revs.date_mode;\n+\t}\n+\n+\tswitch (blame_date_mode) {\n+\tcase DATE_RFC2822:\n+\t\tblame_date_width = sizeof(\"Thu, 19 Oct 2006 16:00:04 -0700\");\n+\t\tbreak;\n+\tcase DATE_ISO8601:\n+\t\tblame_date_width = sizeof(\"2006-10-19 16:00:04 -0700\");\n+\t\tbreak;\n+\tcase DATE_SHORT:\n+\t\tblame_date_width = sizeof(\"2006-10-19\");\n+\t\tbreak;\n+\tcase DATE_RELATIVE:\n+\t\t/* unfortunately \"normal\" is the fallback for \"relative\" */\n+\t\t/* blame_date_width = sizeof(\"14 minutes ago\"); */\n+\t\t/* break; */\n+\tcase DATE_LOCAL:\n+\tcase DATE_NORMAL:\n+\t\tblame_date_width = sizeof(\"Thu Oct 19 16:00:04 2006 -0700\");\n+\t\tbreak;\n+\t}\n+\tblame_date_width -= 1; /* strip the null */\n \n \tif (DIFF_OPT_TST(&revs.diffopt, FIND_COPIES_HARDER))\n \t\topt |= (PICKAXE_BLAME_COPY | PICKAXE_BLAME_MOVE |\n-- \n1.6.2.rc1.14.g07c3.dirty\n"},{"id":"105791","messageId":"7vwsbiz8pg.fsf@gitster.siamese.dyndns.org","threadId":"17926","inReplyTo":"1235170271-10694-1-git-send-email-eletuchy@gmail.com","subject":"Re: [PATCH 1/2] Make git blame's date output format configurable, like git log","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-02-22T17:23:55Z","receivedAt":"2009-02-22T17:23:55Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Looked sensible, queued.\n\nThanks.\n"},{"id":"105828","messageId":"20090222230358.GA19011@coredump.intra.peff.net","threadId":"17926","inReplyTo":"1235170271-10694-1-git-send-email-eletuchy@gmail.com","subject":"Re: [PATCH 1/2] Make git blame's date output format configurable, like git log","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-02-22T23:03:58Z","receivedAt":"2009-02-22T23:03:58Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Feb 20, 2009 at 02:51:11PM -0800, eletuchy@gmail.com wrote:\n\n> @@ -1975,6 +1975,9 @@ static int git_blame_config(const char *var, const char *value, void *cb)\n>  \t\tblank_boundary = git_config_bool(var, value);\n>  \t\treturn 0;\n>  \t}\n> +\tif (!strcmp(var, \"blame.date\") && value[0]) {\n> +\t\tblame_date_mode = parse_date_format(value);\n> +\t}\n>  \treturn git_default_config(var, value, cb);\n>  }\n\nWhen there is a config value we are expecting to have a value rather\nthan a boolean, we usually print an error rather than silently\ndiscarding. IOW, something like this:\n\n  if (!strcmp(var, \"blame.date\")) {\n          if (!value)\n                  return config_error_nonbool(var);\n          blame_date_mode = parse_date_format(value);\n  }\n\n> +\tswitch (blame_date_mode) {\n> +\tcase DATE_RFC2822:\n> +\t\tblame_date_width = sizeof(\"Thu, 19 Oct 2006 16:00:04 -0700\");\n> +\t\tbreak;\n> +\tcase DATE_ISO8601:\n> +\t\tblame_date_width = sizeof(\"2006-10-19 16:00:04 -0700\");\n> +\t\tbreak;\n> +\tcase DATE_SHORT:\n> +\t\tblame_date_width = sizeof(\"2006-10-19\");\n> +\t\tbreak;\n> +\tcase DATE_RELATIVE:\n> +\t\t/* unfortunately \"normal\" is the fallback for \"relative\" */\n> +\t\t/* blame_date_width = sizeof(\"14 minutes ago\"); */\n> +\t\t/* break; */\n> +\tcase DATE_LOCAL:\n> +\tcase DATE_NORMAL:\n> +\t\tblame_date_width = sizeof(\"Thu Oct 19 16:00:04 2006 -0700\");\n> +\t\tbreak;\n> +\t}\n> +\tblame_date_width -= 1; /* strip the null */\n\nMaybe this should be a date_format_width() library function?\n\n\nOther than that, the patch looks reasonable to me.\n\n-Peff\n"},{"id":"105887","messageId":"fbb390660902230109k15ed55b7le2ab08bb7dc274b6@mail.gmail.com","threadId":"17926","inReplyTo":"20090222230358.GA19011@coredump.intra.peff.net","subject":"Re: [PATCH 1/2] Make git blame's date output format configurable, like git log","fromName":"Eugene Letuchy","fromEmail":"eletuchy@gmail.com","sentAt":"2009-02-23T09:09:13Z","receivedAt":"2009-02-23T09:09:13Z","isPatch":true,"sender":{"key":"eletuchy@gmail.com","avatar":null},"body":"On Sun, Feb 22, 2009 at 3:03 PM, Jeff King <peff@peff.net> wrote:\n> On Fri, Feb 20, 2009 at 02:51:11PM -0800, eletuchy@gmail.com wrote:\n>\n>> @@ -1975,6 +1975,9 @@ static int git_blame_config(const char *var, const char *value, void *cb)\n>>               blank_boundary = git_config_bool(var, value);\n>>               return 0;\n>>       }\n>> +     if (!strcmp(var, \"blame.date\") && value[0]) {\n>> +             blame_date_mode = parse_date_format(value);\n>> +     }\n>>       return git_default_config(var, value, cb);\n>>  }\n>\n> When there is a config value we are expecting to have a value rather\n> than a boolean, we usually print an error rather than silently\n> discarding. IOW, something like this:\n>\n>  if (!strcmp(var, \"blame.date\")) {\n>          if (!value)\n>                  return config_error_nonbool(var);\n>          blame_date_mode = parse_date_format(value);\n>  }\n>\n\nI'll make that change to the patch.\n\n>> +     switch (blame_date_mode) {\n>> +     case DATE_RFC2822:\n>> +             blame_date_width = sizeof(\"Thu, 19 Oct 2006 16:00:04 -0700\");\n>> +             break;\n>> +     case DATE_ISO8601:\n>> +             blame_date_width = sizeof(\"2006-10-19 16:00:04 -0700\");\n>> +             break;\n>> +     case DATE_SHORT:\n>> +             blame_date_width = sizeof(\"2006-10-19\");\n>> +             break;\n>> +     case DATE_RELATIVE:\n>> +             /* unfortunately \"normal\" is the fallback for \"relative\" */\n>> +             /* blame_date_width = sizeof(\"14 minutes ago\"); */\n>> +             /* break; */\n>> +     case DATE_LOCAL:\n>> +     case DATE_NORMAL:\n>> +             blame_date_width = sizeof(\"Thu Oct 19 16:00:04 2006 -0700\");\n>> +             break;\n>> +     }\n>> +     blame_date_width -= 1; /* strip the null */\n>\n> Maybe this should be a date_format_width() library function?\n>\n\nI think that's a possible change, but unfortunately my next two\npatches would not apply cleanly with a date_format_width change.\n\nI'm a n00b with respect to git contribution, but is there a procedure\nfor pushing my blame_date branch remotely so that it's possible to\ntrack a series of patches?\n\n>\n> Other than that, the patch looks reasonable to me.\n>\n> -Peff\n>\n\n\n\n-- \nEugene\n"},{"id":"105917","messageId":"7v3ae5un84.fsf@gitster.siamese.dyndns.org","threadId":"17926","inReplyTo":"20090222230358.GA19011@coredump.intra.peff.net","subject":"Re: [PATCH 1/2] Make git blame's date output format configurable, like git log","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-02-23T16:33:47Z","receivedAt":"2009-02-23T16:33:47Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> On Fri, Feb 20, 2009 at 02:51:11PM -0800, eletuchy@gmail.com wrote:\n>\n>> @@ -1975,6 +1975,9 @@ static int git_blame_config(const char *var, const char *value, void *cb)\n>>  \t\tblank_boundary = git_config_bool(var, value);\n>>  \t\treturn 0;\n>>  \t}\n>> +\tif (!strcmp(var, \"blame.date\") && value[0]) {\n>> +\t\tblame_date_mode = parse_date_format(value);\n>> +\t}\n>>  \treturn git_default_config(var, value, cb);\n>>  }\n>\n> When there is a config value we are expecting to have a value rather\n> than a boolean, we usually print an error rather than silently\n> discarding.\n\nOops, missed that.  Yes, this needs fixing.\n\nThanks.\n"},{"id":"105971","messageId":"20090224050028.GB4615@coredump.intra.peff.net","threadId":"17926","inReplyTo":"fbb390660902230109k15ed55b7le2ab08bb7dc274b6@mail.gmail.com","subject":"Re: [PATCH 1/2] Make git blame's date output format configurable, like git log","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-02-24T05:00:28Z","receivedAt":"2009-02-24T05:00:28Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, Feb 23, 2009 at 01:09:13AM -0800, Eugene Letuchy wrote:\n\n> > Maybe this should be a date_format_width() library function?\n> \n> I think that's a possible change, but unfortunately my next two\n> patches would not apply cleanly with a date_format_width change.\n> \n> I'm a n00b with respect to git contribution, but is there a procedure\n> for pushing my blame_date branch remotely so that it's possible to\n> track a series of patches?\n\nUpdating previous work depends on whether it has been picked up in\n'next' by Junio; once patches are there, they cannot be rewritten. In\nthat case, you can send a follow-up patch.\n\nIn your case, though, the patch is still in 'pu', so you can repost. So\nI think it makes sense to use \"rebase -i\" (or the tool of your choice)\nto make a cleaned up series, and then repost the whole thing as a\nseries.\n\n-Peff\n"}]}