Skip to content

Commit 7dfe8ad

Browse files
committed
commit: pass author/committer info to hooks
When lying the author name via GIT_AUTHOR_NAME environment variable to "git commit", the hooks run by the command saw it and could act on the name that will be recorded in the final commit. When the user uses the "--author" option from the command line, the command should give the same information to the hook, and back when "git command" was a scripted Porcelain, it did set the environment variable and hooks can learn the author name from it. However, when the command was reimplemented in C, the rewritten code was not very faithful to the original, and hooks stopped getting the authorship information given with "--author". Fix this by exporting the necessary environment variables. Signed-off-by: Junio C Hamano <[email protected]>
1 parent 0486198 commit 7dfe8ad

File tree

2 files changed

+20
-4
lines changed

2 files changed

+20
-4
lines changed

builtin/commit.c

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -533,9 +533,20 @@ static int is_a_merge(const struct commit *current_head)
533533

534534
static const char sign_off_header[] = "Signed-off-by: ";
535535

536+
static void export_one(const char *var, const char *s, const char *e, int hack)
537+
{
538+
struct strbuf buf = STRBUF_INIT;
539+
if (hack)
540+
strbuf_addch(&buf, hack);
541+
strbuf_addf(&buf, "%.*s", (int)(e - s), s);
542+
setenv(var, buf.buf, 1);
543+
strbuf_release(&buf);
544+
}
545+
536546
static void determine_author_info(struct strbuf *author_ident)
537547
{
538548
char *name, *email, *date;
549+
struct ident_split author;
539550

540551
name = getenv("GIT_AUTHOR_NAME");
541552
email = getenv("GIT_AUTHOR_EMAIL");
@@ -585,6 +596,11 @@ static void determine_author_info(struct strbuf *author_ident)
585596
date = force_date;
586597
strbuf_addstr(author_ident, fmt_ident(name, email, date,
587598
IDENT_ERROR_ON_NO_NAME));
599+
if (!split_ident_line(&author, author_ident->buf, author_ident->len)) {
600+
export_one("GIT_AUTHOR_NAME", author.name_begin, author.name_end, 0);
601+
export_one("GIT_AUTHOR_EMAIL", author.mail_begin, author.mail_end, 0);
602+
export_one("GIT_AUTHOR_DATE", author.date_begin, author.tz_end, '@');
603+
}
588604
}
589605

590606
static int ends_rfc2822_footer(struct strbuf *sb)
@@ -652,6 +668,9 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
652668
int ident_shown = 0;
653669
int clean_message_contents = (cleanup_mode != CLEANUP_NONE);
654670

671+
/* This checks and barfs if author is badly specified */
672+
determine_author_info(author_ident);
673+
655674
if (!no_verify && run_hook(index_file, "pre-commit", NULL))
656675
return 0;
657676

@@ -771,9 +790,6 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
771790

772791
strbuf_release(&sb);
773792

774-
/* This checks and barfs if author is badly specified */
775-
determine_author_info(author_ident);
776-
777793
/* This checks if committer ident is explicitly given */
778794
strbuf_addstr(&committer_ident, git_committer_info(0));
779795
if (use_editor && include_status) {

t/t7503-pre-commit-hook.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ test_expect_success 'with failing hook requiring GIT_PREFIX' '
118118
git checkout -- file
119119
'
120120

121-
test_expect_failure 'check the author in hook' '
121+
test_expect_success 'check the author in hook' '
122122
write_script "$HOOK" <<-\EOF &&
123123
test "$GIT_AUTHOR_NAME" = "New Author" &&
124124
test "$GIT_AUTHOR_EMAIL" = "[email protected]"

0 commit comments

Comments
 (0)