Code

commit: pass author/committer info to hooks
[git.git] / builtin / commit.c
index eba1377eb32c02e57c46364c381df940afa66048..57a60f9f4bf8d89c04433ba48fc76d0ced274edd 100644 (file)
@@ -196,16 +196,16 @@ static void determine_whence(struct wt_status *s)
 
 static const char *whence_s(void)
 {
-       char *s = "";
+       const char *s = "";
 
        switch (whence) {
        case FROM_COMMIT:
                break;
        case FROM_MERGE:
-               s = "merge";
+               s = _("merge");
                break;
        case FROM_CHERRY_PICK:
-               s = "cherry-pick";
+               s = _("cherry-pick");
                break;
        }
 
@@ -533,9 +533,20 @@ static int is_a_merge(const struct commit *current_head)
 
 static const char sign_off_header[] = "Signed-off-by: ";
 
+static void export_one(const char *var, const char *s, const char *e, int hack)
+{
+       struct strbuf buf = STRBUF_INIT;
+       if (hack)
+               strbuf_addch(&buf, hack);
+       strbuf_addf(&buf, "%.*s", (int)(e - s), s);
+       setenv(var, buf.buf, 1);
+       strbuf_release(&buf);
+}
+
 static void determine_author_info(struct strbuf *author_ident)
 {
        char *name, *email, *date;
+       struct ident_split author;
 
        name = getenv("GIT_AUTHOR_NAME");
        email = getenv("GIT_AUTHOR_EMAIL");
@@ -543,6 +554,7 @@ static void determine_author_info(struct strbuf *author_ident)
 
        if (author_message) {
                const char *a, *lb, *rb, *eol;
+               size_t len;
 
                a = strstr(author_message_buffer, "\nauthor ");
                if (!a)
@@ -563,6 +575,11 @@ static void determine_author_info(struct strbuf *author_ident)
                                         (a + strlen("\nauthor "))));
                email = xmemdupz(lb + strlen("<"), rb - (lb + strlen("<")));
                date = xmemdupz(rb + strlen("> "), eol - (rb + strlen("> ")));
+               len = eol - (rb + strlen("> "));
+               date = xmalloc(len + 2);
+               *date = '@';
+               memcpy(date + 1, rb + strlen("> "), len);
+               date[len + 1] = '\0';
        }
 
        if (force_author) {
@@ -579,6 +596,11 @@ static void determine_author_info(struct strbuf *author_ident)
                date = force_date;
        strbuf_addstr(author_ident, fmt_ident(name, email, date,
                                              IDENT_ERROR_ON_NO_NAME));
+       if (!split_ident_line(&author, author_ident->buf, author_ident->len)) {
+               export_one("GIT_AUTHOR_NAME", author.name_begin, author.name_end, 0);
+               export_one("GIT_AUTHOR_EMAIL", author.mail_begin, author.mail_end, 0);
+               export_one("GIT_AUTHOR_DATE", author.date_begin, author.tz_end, '@');
+       }
 }
 
 static int ends_rfc2822_footer(struct strbuf *sb)
@@ -646,6 +668,9 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
        int ident_shown = 0;
        int clean_message_contents = (cleanup_mode != CLEANUP_NONE);
 
+       /* This checks and barfs if author is badly specified */
+       determine_author_info(author_ident);
+
        if (!no_verify && run_hook(index_file, "pre-commit", NULL))
                return 0;
 
@@ -765,9 +790,6 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
 
        strbuf_release(&sb);
 
-       /* This checks and barfs if author is badly specified */
-       determine_author_info(author_ident);
-
        /* This checks if committer ident is explicitly given */
        strbuf_addstr(&committer_ident, git_committer_info(0));
        if (use_editor && include_status) {