git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 3/3] commit: pass author/committer info to hooks

From
Junio C Hamano <gitster@pobox.com>
Date
Mar 11, 2012, 11:11 UTC
Message-ID
<7vsjhfxuhh.fsf_-_@alter.siamese.dyndns.org>
In-Reply-To
<7vwr6rxul6.fsf_-_@alter.siamese.dyndns.org>

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 <gitster@pobox.com>
---
 * This is the last patch of the simpler of the two approaches, that
   builds on top of the two common preparatory patches.  It uses setenv()
   to directly affect the execution environment of "git commit" process,
   which is closer to the original scripted Porcelain implementation.
 builtin/commit.c           |   22 +++++++++++++++++++---
 t/t7503-pre-commit-hook.sh |    2 +-
 2 files changed, 20 insertions(+), 4 deletions(-)
diff --git a/builtin/commit.c b/builtin/commit.c
index eae5a29..57a60f9 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -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");
@@ -585,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)
@@ -652,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;
 
@@ -771,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) {
diff --git a/t/t7503-pre-commit-hook.sh b/t/t7503-pre-commit-hook.sh
index fc6de5b..9301a0c 100755
--- a/t/t7503-pre-commit-hook.sh
+++ b/t/t7503-pre-commit-hook.sh
@@ -118,7 +118,7 @@ test_expect_success 'with failing hook requiring GIT_PREFIX' '
 	git checkout -- file
 '
 
-test_expect_failure 'check the author in hook' '
+test_expect_success 'check the author in hook' '
 	cat >"$HOOK" <<-\EOF &&
 	test "$GIT_AUTHOR_NAME" = "New Author" &&
 	test "$GIT_AUTHOR_EMAIL" = "newauthor@example.com"
-- 
1.7.10.rc0.33.g8866af
Previous: Junio C HamanoNext: Jeff King
Message 10 of 13 in “Stop a git commit by a specific author using pre-commit hook”
  1. Adrian CornishMar 9, 2012
  2. Neal KreitzingerMar 10, 2012
  3. Junio C HamanoMar 10, 2012
  4. Neal KreitzingerMar 10, 2012
  5. Junio C HamanoMar 11, 2012
  6. 3/4 test: does pre-commit-hook learn authorship?Junio C Hamano, Mar 11, 2012
  7. Johannes SixtMar 11, 2012
  8. Junio C HamanoMar 11, 2012
  9. 3/4 ident.c: add split_ident_line() to parse formatted ident lineJunio C Hamano, Mar 11, 2012
  10. 3/3 commit: pass author/committer info to hooksJunio C Hamano, Mar 11, 2012
  11. Jeff KingMar 12, 2012
  12. 3/4 run_hook(): enhance the interface to pass arbitrary environmentJunio C Hamano, Mar 11, 2012
  13. 4/4 commit: pass author/committer info to hooksJunio C Hamano, Mar 11, 2012

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.