@@ -695,11 +695,14 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
int clean_message_contents = (cleanup_mode != COMMIT_MSG_CLEANUP_NONE);
int old_display_comment_prefix;
int merge_contains_scissors = 0;
+ int message_from_stdin = logfile && !strcmp(logfile, "-");
+ const unsigned hook_flags = message_from_stdin ? 0 : RUN_HOOK_ALLOW_STDIN;
/* This checks and barfs if author is badly specified */
determine_author_info(author_ident);
- if (!no_verify && run_commit_hook(use_editor, index_file, 0, "pre-commit", NULL))
+ if (!no_verify &&
+ run_commit_hook(use_editor, index_file, hook_flags, "pre-commit", NULL))
return 0;
if (squash_message) {
@@ -724,7 +727,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
if (have_option_m && !fixup_message) {
strbuf_addbuf(&sb, &message);
hook_arg1 = "message";
- } else if (logfile && !strcmp(logfile, "-")) {
+ } else if (message_from_stdin) {
if (isatty(0))
fprintf(stderr, _("(reading log message from standard input)\n"));
if (strbuf_read(&sb, 0, 0) < 0)
@@ -998,7 +1001,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
return 0;
}
- if (run_commit_hook(use_editor, index_file, 0, "prepare-commit-msg",
+ if (run_commit_hook(use_editor, index_file, RUN_HOOK_ALLOW_STDIN, "prepare-commit-msg",
git_path_commit_editmsg(), hook_arg1, hook_arg2, NULL))
return 0;
@@ -1015,7 +1018,8 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
}
if (!no_verify &&
- run_commit_hook(use_editor, index_file, 0, "commit-msg", git_path_commit_editmsg(), NULL)) {
+ run_commit_hook(use_editor, index_file, RUN_HOOK_ALLOW_STDIN, "commit-msg",
+ git_path_commit_editmsg(), NULL)) {
return 0;
}
@@ -1701,7 +1705,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
repo_rerere(the_repository, 0);
run_auto_maintenance(quiet);
- run_commit_hook(use_editor, get_index_file(), 0, "post-commit", NULL);
+ run_commit_hook(use_editor, get_index_file(), RUN_HOOK_ALLOW_STDIN, "post-commit", NULL);
if (amend && !no_post_rewrite) {
commit_post_rewrite(the_repository, current_head, &oid);
}
@@ -836,8 +836,11 @@ static void prepare_to_commit(struct commit_list *remoteheads)
struct strbuf msg = STRBUF_INIT;
const char *index_file = get_index_file();
- if (!no_verify && run_commit_hook(0 < option_edit, index_file, 0, "pre-merge-commit", NULL))
+ if (!no_verify &&
+ run_commit_hook(0 < option_edit, index_file, RUN_HOOK_ALLOW_STDIN,
+ "pre-merge-commit", NULL)) {
abort_commit(remoteheads, NULL);
+ }
/*
* Re-read the index as pre-merge-commit hook could have updated it,
* and write it out as a tree. We must do this before we invoke
@@ -864,8 +867,9 @@ static void prepare_to_commit(struct commit_list *remoteheads)
append_signoff(&msg, ignore_non_trailer(msg.buf, msg.len), 0);
write_merge_heads(remoteheads);
write_file_buf(git_path_merge_msg(the_repository), msg.buf, msg.len);
- if (run_commit_hook(0 < option_edit, get_index_file(), 0, "prepare-commit-msg",
- git_path_merge_msg(the_repository), "merge", NULL))
+ if (run_commit_hook(0 < option_edit, get_index_file(), RUN_HOOK_ALLOW_STDIN,
+ "prepare-commit-msg", git_path_merge_msg(the_repository),
+ "merge", NULL))
abort_commit(remoteheads, NULL);
if (0 < option_edit) {
if (launch_editor(git_path_merge_msg(the_repository), NULL, NULL))
@@ -873,7 +877,7 @@ static void prepare_to_commit(struct commit_list *remoteheads)
}
if (!no_verify && run_commit_hook(0 < option_edit, get_index_file(),
- 0, "commit-msg",
+ RUN_HOOK_ALLOW_STDIN, "commit-msg",
git_path_merge_msg(the_repository), NULL))
abort_commit(remoteheads, NULL);
@@ -1203,8 +1203,8 @@ static int run_prepare_commit_msg_hook(struct repository *r,
} else {
arg1 = "message";
}
- if (run_commit_hook(0, r->index_file, 0, "prepare-commit-msg", name,
- arg1, arg2, NULL))
+ if (run_commit_hook(0, r->index_file, RUN_HOOK_ALLOW_STDIN,
+ "prepare-commit-msg", name, arg1, arg2, NULL))
ret = error(_("'prepare-commit-msg' hook failed"));
return ret;
@@ -1528,7 +1528,7 @@ static int try_to_commit(struct repository *r,
goto out;
}
- run_commit_hook(0, r->index_file, 0, "post-commit", NULL);
+ run_commit_hook(0, r->index_file, RUN_HOOK_ALLOW_STDIN, "post-commit", NULL);
if (flags & AMEND_MSG)
commit_post_rewrite(r, current_head, oid);
@@ -7,6 +7,7 @@ test_description='pre-commit and pre-merge-commit hooks'
HOOKDIR="$(git rev-parse --git-dir)/hooks"
PRECOMMIT="$HOOKDIR/pre-commit"
PREMERGE="$HOOKDIR/pre-merge-commit"
+POSTCOMMIT="$HOOKDIR/post-commit"
# Prepare sample scripts that write their $0 to actual_hooks
test_expect_success 'sample script setup' '
@@ -28,11 +29,14 @@ test_expect_success 'sample script setup' '
echo $0 >>actual_hooks
test $GIT_PREFIX = "success/"
EOF
- write_script "$HOOKDIR/check-author.sample" <<-\EOF
+ write_script "$HOOKDIR/check-author.sample" <<-\EOF &&
echo $0 >>actual_hooks
test "$GIT_AUTHOR_NAME" = "New Author" &&
test "$GIT_AUTHOR_EMAIL" = "newauthor@example.com"
EOF
+ write_script "$HOOKDIR/user-input.sample" <<-\EOF
+ ! read -r line || echo "$line" >hook_input
+ EOF
'
test_expect_success 'root commit' '
@@ -278,4 +282,44 @@ test_expect_success 'check the author in hook' '
test_cmp expected_hooks actual_hooks
'
+test_expect_success 'with user input' '
+ test_when_finished "rm -f \"$PRECOMMIT\" user_input hook_input" &&
+ cp "$HOOKDIR/user-input.sample" "$PRECOMMIT" &&
+ echo "user input" >user_input &&
+ echo "more" >>file &&
+ git add file &&
+ git commit -m "more" <user_input &&
+ test_cmp user_input hook_input
+'
+
+test_expect_success 'with user input combined with -F -' '
+ test_when_finished "rm -f \"$PRECOMMIT\" user_input hook_input" &&
+ cp "$HOOKDIR/user-input.sample" "$PRECOMMIT" &&
+ echo "user input" >user_input &&
+ echo "more" >>file &&
+ git add file &&
+ git commit -F - <user_input &&
+ ! test_path_is_file hook_input
+'
+
+test_expect_success 'post-commit with user input' '
+ test_when_finished "rm -f \"$POSTCOMMIT\" user_input hook_input" &&
+ cp "$HOOKDIR/user-input.sample" "$POSTCOMMIT" &&
+ echo "user input" >user_input &&
+ echo "more" >>file &&
+ git add file &&
+ git commit -m "more" <user_input &&
+ test_cmp user_input hook_input
+'
+
+test_expect_success 'with user input (merge)' '
+ test_when_finished "rm -f \"$PREMERGE\" user_input hook_input" &&
+ cp "$HOOKDIR/user-input.sample" "$PREMERGE" &&
+ echo "user input" >user_input &&
+ git checkout side &&
+ git merge -m "merge master" master <user_input &&
+ git checkout master &&
+ test_cmp user_input hook_input
+'
+
test_done
@@ -294,5 +294,20 @@ test_expect_success 'hook is called for reword during `rebase -i`' '
'
+# now a hook that accepts input and writes it as the commit message
+cat >"$HOOK" <<'EOF'
+#!/bin/sh
+! read -r line || echo "$line" >"$1"
+EOF
+chmod +x "$HOOK"
+
+test_expect_success 'hook with user input' '
+
+ echo "additional" >>file &&
+ git add file &&
+ echo "user input" | git commit -m "additional" &&
+ commit_msg_is "user input"
+
+'
test_done
@@ -91,6 +91,11 @@ else
fi
test "$GIT_EDITOR" = : && source="$source (no editor)"
+if read -r line
+then
+ source="$source $line"
+fi
+
if test $rebasing = 1
then
echo "$source $(get_last_cmd)" >"$1"
@@ -113,6 +118,15 @@ test_expect_success 'with hook (-m)' '
'
+test_expect_success 'with hook (-m and input)' '
+
+ echo "more" >>file &&
+ git add file &&
+ echo "user input" | git commit -m "more" &&
+ test "$(git log -1 --pretty=format:%s)" = "message (no editor) user input"
+
+'
+
test_expect_success 'with hook (-m editor)' '
echo "more" >> file &&