From 4701026352ada1ebc36532272ca1e12897b1de11 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Thu, 1 May 2014 21:06:57 -0400 Subject: commit: use split_ident_line to compare author/committer Instead of string-wise comparing the author/committer lines with their timestamps truncated, we can use split_ident_line and ident_cmp. These functions are more robust than our ad-hoc parsing, though in practice it should not matter, as we just generated these ident lines ourselves. However, this will also allow us easy access to the timestamp and tz fields in future patches. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- builtin/commit.c | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) (limited to 'builtin/commit.c') diff --git a/builtin/commit.c b/builtin/commit.c index 9cfef6c6cc..728cc9bbfc 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -585,13 +585,11 @@ static void determine_author_info(struct strbuf *author_ident) } } -static char *cut_ident_timestamp_part(char *string) +static void split_ident_or_die(struct ident_split *id, const struct strbuf *buf) { - char *ket = strrchr(string, '>'); - if (!ket || ket[1] != ' ') - die(_("Malformed ident string: '%s'"), string); - *++ket = '\0'; - return ket; + if (split_ident_line(id, buf->buf, buf->len) || + !sane_ident_split(id)) + die(_("Malformed ident string: '%s'"), buf->buf); } static int prepare_to_commit(const char *index_file, const char *prefix, @@ -755,7 +753,8 @@ static int prepare_to_commit(const char *index_file, const char *prefix, if (use_editor && include_status) { int ident_shown = 0; int saved_color_setting; - char *ai_tmp, *ci_tmp; + struct ident_split ci, ai; + if (whence != FROM_COMMIT) { if (cleanup_mode == CLEANUP_SCISSORS) wt_status_add_cut_line(s->fp); @@ -795,21 +794,24 @@ static int prepare_to_commit(const char *index_file, const char *prefix, status_printf_ln(s, GIT_COLOR_NORMAL, "%s", only_include_assumed); - ai_tmp = cut_ident_timestamp_part(author_ident->buf); - ci_tmp = cut_ident_timestamp_part(committer_ident.buf); - if (strcmp(author_ident->buf, committer_ident.buf)) + split_ident_or_die(&ai, author_ident); + split_ident_or_die(&ci, &committer_ident); + + if (ident_cmp(&ai, &ci)) status_printf_ln(s, GIT_COLOR_NORMAL, _("%s" - "Author: %s"), + "Author: %.*s <%.*s>"), ident_shown++ ? "" : "\n", - author_ident->buf); + (int)(ai.name_end - ai.name_begin), ai.name_begin, + (int)(ai.mail_end - ai.mail_begin), ai.mail_begin); if (!committer_ident_sufficiently_given()) status_printf_ln(s, GIT_COLOR_NORMAL, _("%s" - "Committer: %s"), + "Committer: %.*s <%.*s>"), ident_shown++ ? "" : "\n", - committer_ident.buf); + (int)(ci.name_end - ci.name_begin), ci.name_begin, + (int)(ci.mail_end - ci.mail_begin), ci.mail_begin); if (ident_shown) status_printf_ln(s, GIT_COLOR_NORMAL, ""); @@ -818,9 +820,6 @@ static int prepare_to_commit(const char *index_file, const char *prefix, s->use_color = 0; commitable = run_status(s->fp, index_file, prefix, 1, s); s->use_color = saved_color_setting; - - *ai_tmp = ' '; - *ci_tmp = ' '; } else { unsigned char sha1[20]; const char *parent = "HEAD"; -- cgit v1.2.1 From b7242b8c9e4b3c57a07c2a76d0337389605aadcc Mon Sep 17 00:00:00 2001 From: Jeff King Date: Thu, 1 May 2014 21:10:01 -0400 Subject: commit: print "Date" line when the user has set date When we make a commit and the author is not the same as the committer (e.g., because you used "-c $commit" or "--author=$somebody"), we print the author's name and email in both the commit-message template and as part of the commit summary. This is a safety check to give the user a chance to confirm that we are doing what they expect. This patch brings the same safety for the "date" field, which may be set by "-c" or by using "--date". Note that we explicitly do not set it for $GIT_AUTHOR_DATE, as it is probably not of interest when "git commit" is being fed its parameters by a script. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- builtin/commit.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'builtin/commit.c') diff --git a/builtin/commit.c b/builtin/commit.c index 728cc9bbfc..a25661f343 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -592,6 +592,11 @@ static void split_ident_or_die(struct ident_split *id, const struct strbuf *buf) die(_("Malformed ident string: '%s'"), buf->buf); } +static int author_date_is_interesting(void) +{ + return author_message || force_date; +} + static int prepare_to_commit(const char *index_file, const char *prefix, struct commit *current_head, struct wt_status *s, @@ -805,6 +810,13 @@ static int prepare_to_commit(const char *index_file, const char *prefix, (int)(ai.name_end - ai.name_begin), ai.name_begin, (int)(ai.mail_end - ai.mail_begin), ai.mail_begin); + if (author_date_is_interesting()) + status_printf_ln(s, GIT_COLOR_NORMAL, + _("%s" + "Date: %s"), + ident_shown++ ? "" : "\n", + show_ident_date(&ai, DATE_NORMAL)); + if (!committer_ident_sufficiently_given()) status_printf_ln(s, GIT_COLOR_NORMAL, _("%s" @@ -1355,6 +1367,13 @@ static void print_summary(const char *prefix, const unsigned char *sha1, strbuf_addstr(&format, "\n Author: "); strbuf_addbuf_percentquote(&format, &author_ident); } + if (author_date_is_interesting()) { + struct strbuf date = STRBUF_INIT; + format_commit_message(commit, "%ad", &date, &pctx); + strbuf_addstr(&format, "\n Date: "); + strbuf_addbuf_percentquote(&format, &date); + strbuf_release(&date); + } if (!committer_ident_sufficiently_given()) { strbuf_addstr(&format, "\n Committer: "); strbuf_addbuf_percentquote(&format, &committer_ident); -- cgit v1.2.1 From 14ac2864dcd566a025e449ab9db6b5dc57744a32 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Thu, 1 May 2014 21:12:42 -0400 Subject: commit: accept more date formats for "--date" Right now we pass off the string found by "--date" straight to the fmt_ident function, which will use our strict parse_date to normalize it. However, this means obvious things like "--date=now" or "--date=2.days.ago" will not work. Instead, let's fallback to the approxidate function to handle this for us. Note that we must try parse_date ourselves first, even though approxidate will try strict parsing itself. The reason is that approxidate throws away any timezone information it sees from the strict parsing, and we want to preserve it. So asking for: git commit --date="@1234567890 -0700" continues to set the date in -0700, regardless of what the local timezone is. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- builtin/commit.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) (limited to 'builtin/commit.c') diff --git a/builtin/commit.c b/builtin/commit.c index a25661f343..d1c90db95d 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -526,10 +526,29 @@ static int sane_ident_split(struct ident_split *person) return 1; } +static int parse_force_date(const char *in, char *out, int len) +{ + if (len < 1) + return -1; + *out++ = '@'; + len--; + + if (parse_date(in, out, len) < 0) { + int errors = 0; + unsigned long t = approxidate_careful(in, &errors); + if (errors) + return -1; + snprintf(out, len, "%lu", t); + } + + return 0; +} + static void determine_author_info(struct strbuf *author_ident) { char *name, *email, *date; struct ident_split author; + char date_buf[64]; name = getenv("GIT_AUTHOR_NAME"); email = getenv("GIT_AUTHOR_EMAIL"); @@ -574,8 +593,12 @@ static void determine_author_info(struct strbuf *author_ident) email = xstrndup(lb + 2, rb - (lb + 2)); } - if (force_date) - date = force_date; + if (force_date) { + if (parse_force_date(force_date, date_buf, sizeof(date_buf))) + die(_("invalid date format: %s"), force_date); + date = date_buf; + } + strbuf_addstr(author_ident, fmt_ident(name, email, date, IDENT_STRICT)); if (!split_ident_line(&author, author_ident->buf, author_ident->len) && sane_ident_split(&author)) { -- cgit v1.2.1