| #!/bin/sh | 
 |  | 
 | test_description='prepare-commit-msg hook' | 
 |  | 
 | GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main | 
 | export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME | 
 |  | 
 | . ./test-lib.sh | 
 |  | 
 | test_expect_success 'set up commits for rebasing' ' | 
 | 	test_commit root && | 
 | 	test_commit a a a && | 
 | 	test_commit b b b && | 
 | 	git checkout -b rebase-me root && | 
 | 	test_commit rebase-a a aa && | 
 | 	test_commit rebase-b b bb && | 
 | 	for i in $(test_seq 1 13) | 
 | 	do | 
 | 		test_commit rebase-$i c $i || return 1 | 
 | 	done && | 
 | 	git checkout main && | 
 |  | 
 | 	cat >rebase-todo <<-EOF | 
 | 	pick $(git rev-parse rebase-a) | 
 | 	pick $(git rev-parse rebase-b) | 
 | 	fixup $(git rev-parse rebase-1) | 
 | 	fixup $(git rev-parse rebase-2) | 
 | 	pick $(git rev-parse rebase-3) | 
 | 	fixup $(git rev-parse rebase-4) | 
 | 	squash $(git rev-parse rebase-5) | 
 | 	reword $(git rev-parse rebase-6) | 
 | 	squash $(git rev-parse rebase-7) | 
 | 	fixup $(git rev-parse rebase-8) | 
 | 	fixup $(git rev-parse rebase-9) | 
 | 	edit $(git rev-parse rebase-10) | 
 | 	squash $(git rev-parse rebase-11) | 
 | 	squash $(git rev-parse rebase-12) | 
 | 	edit $(git rev-parse rebase-13) | 
 | 	EOF | 
 | ' | 
 |  | 
 | test_expect_success 'with no hook' ' | 
 |  | 
 | 	echo "foo" > file && | 
 | 	git add file && | 
 | 	git commit -m "first" | 
 |  | 
 | ' | 
 |  | 
 | test_expect_success 'setup fake editor for interactive editing' ' | 
 | 	write_script fake-editor <<-\EOF && | 
 | 	exit 0 | 
 | 	EOF | 
 |  | 
 | 	## Not using test_set_editor here so we can easily ensure the editor variable | 
 | 	## is only set for the editor tests | 
 | 	FAKE_EDITOR="$(pwd)/fake-editor" && | 
 | 	export FAKE_EDITOR | 
 | ' | 
 |  | 
 | test_expect_success 'setup prepare-commit-msg hook' ' | 
 | 	test_hook --setup prepare-commit-msg <<\EOF | 
 | GIT_DIR=$(git rev-parse --git-dir) | 
 | if test -d "$GIT_DIR/rebase-merge" | 
 | then | 
 | 	rebasing=1 | 
 | else | 
 | 	rebasing=0 | 
 | fi | 
 |  | 
 | get_last_cmd () { | 
 | 	tail -n1 "$GIT_DIR/rebase-merge/done" | { | 
 | 		read cmd id _ | 
 | 		git log --pretty="[$cmd %s]" -n1 $id | 
 | 	} | 
 | } | 
 |  | 
 | if test "$2" = commit | 
 | then | 
 | 	if test $rebasing = 1 | 
 | 	then | 
 | 		source="$3" | 
 | 	else | 
 | 		source=$(git rev-parse "$3") | 
 | 	fi | 
 | else | 
 | 	source=${2-default} | 
 | fi | 
 | test "$GIT_EDITOR" = : && source="$source (no editor)" | 
 |  | 
 | if test $rebasing = 1 | 
 | then | 
 | 	echo "$source $(get_last_cmd)" >"$1" | 
 | else | 
 | 	sed -e "1s/.*/$source/" "$1" >msg.tmp | 
 | 	mv msg.tmp "$1" | 
 | fi | 
 | exit 0 | 
 | EOF | 
 | ' | 
 |  | 
 | echo dummy template > "$(git rev-parse --git-dir)/template" | 
 |  | 
 | test_expect_success 'with hook (-m)' ' | 
 |  | 
 | 	echo "more" >> file && | 
 | 	git add file && | 
 | 	git commit -m "more" && | 
 | 	test "$(git log -1 --pretty=format:%s)" = "message (no editor)" | 
 |  | 
 | ' | 
 |  | 
 | test_expect_success 'with hook (-m editor)' ' | 
 |  | 
 | 	echo "more" >> file && | 
 | 	git add file && | 
 | 	GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit -e -m "more more" && | 
 | 	test "$(git log -1 --pretty=format:%s)" = message | 
 |  | 
 | ' | 
 |  | 
 | test_expect_success 'with hook (-t)' ' | 
 |  | 
 | 	echo "more" >> file && | 
 | 	git add file && | 
 | 	git commit -t "$(git rev-parse --git-dir)/template" && | 
 | 	test "$(git log -1 --pretty=format:%s)" = template | 
 |  | 
 | ' | 
 |  | 
 | test_expect_success 'with hook (-F)' ' | 
 |  | 
 | 	echo "more" >> file && | 
 | 	git add file && | 
 | 	(echo more | git commit -F -) && | 
 | 	test "$(git log -1 --pretty=format:%s)" = "message (no editor)" | 
 |  | 
 | ' | 
 |  | 
 | test_expect_success 'with hook (-F editor)' ' | 
 |  | 
 | 	echo "more" >> file && | 
 | 	git add file && | 
 | 	(echo more more | GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit -e -F -) && | 
 | 	test "$(git log -1 --pretty=format:%s)" = message | 
 |  | 
 | ' | 
 |  | 
 | test_expect_success 'with hook (-C)' ' | 
 |  | 
 | 	head=$(git rev-parse HEAD) && | 
 | 	echo "more" >> file && | 
 | 	git add file && | 
 | 	git commit -C $head && | 
 | 	test "$(git log -1 --pretty=format:%s)" = "$head (no editor)" | 
 |  | 
 | ' | 
 |  | 
 | test_expect_success 'with hook (editor)' ' | 
 |  | 
 | 	echo "more more" >> file && | 
 | 	git add file && | 
 | 	GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit && | 
 | 	test "$(git log -1 --pretty=format:%s)" = default | 
 |  | 
 | ' | 
 |  | 
 | test_expect_success 'with hook (--amend)' ' | 
 |  | 
 | 	head=$(git rev-parse HEAD) && | 
 | 	echo "more" >> file && | 
 | 	git add file && | 
 | 	GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit --amend && | 
 | 	test "$(git log -1 --pretty=format:%s)" = "$head" | 
 |  | 
 | ' | 
 |  | 
 | test_expect_success 'with hook (-c)' ' | 
 |  | 
 | 	head=$(git rev-parse HEAD) && | 
 | 	echo "more" >> file && | 
 | 	git add file && | 
 | 	GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit -c $head && | 
 | 	test "$(git log -1 --pretty=format:%s)" = "$head" | 
 |  | 
 | ' | 
 |  | 
 | test_expect_success 'with hook (merge)' ' | 
 |  | 
 | 	test_when_finished "git checkout -f main" && | 
 | 	git checkout -B other HEAD@{1} && | 
 | 	echo "more" >>file && | 
 | 	git add file && | 
 | 	git commit -m other && | 
 | 	git checkout - && | 
 | 	git merge --no-ff other && | 
 | 	test "$(git log -1 --pretty=format:%s)" = "merge (no editor)" | 
 | ' | 
 |  | 
 | test_expect_success 'with hook and editor (merge)' ' | 
 |  | 
 | 	test_when_finished "git checkout -f main" && | 
 | 	git checkout -B other HEAD@{1} && | 
 | 	echo "more" >>file && | 
 | 	git add file && | 
 | 	git commit -m other && | 
 | 	git checkout - && | 
 | 	env GIT_EDITOR="\"\$FAKE_EDITOR\"" git merge --no-ff -e other && | 
 | 	test "$(git log -1 --pretty=format:%s)" = "merge" | 
 | ' | 
 |  | 
 | test_rebase () { | 
 | 	expect=$1 && | 
 | 	mode=$2 && | 
 | 	test_expect_$expect "with hook (rebase ${mode:--i})" ' | 
 | 		test_when_finished "\ | 
 | 			git rebase --abort | 
 | 			git checkout -f main | 
 | 			git branch -D tmp" && | 
 | 		git checkout -b tmp rebase-me && | 
 | 		GIT_SEQUENCE_EDITOR="cp rebase-todo" && | 
 | 		GIT_EDITOR="\"$FAKE_EDITOR\"" && | 
 | 		( | 
 | 			export GIT_SEQUENCE_EDITOR GIT_EDITOR && | 
 | 			test_must_fail git rebase -i $mode b && | 
 | 			echo x >a && | 
 | 			git add a && | 
 | 			test_must_fail git rebase --continue && | 
 | 			echo x >b && | 
 | 			git add b && | 
 | 			git commit && | 
 | 			git rebase --continue && | 
 | 			echo y >a && | 
 | 			git add a && | 
 | 			git commit && | 
 | 			git rebase --continue && | 
 | 			echo y >b && | 
 | 			git add b && | 
 | 			git rebase --continue | 
 | 		) && | 
 | 		git log --pretty=%s -g -n18 HEAD@{1} >actual && | 
 | 		test_cmp "$TEST_DIRECTORY/t7505/expected-rebase${mode:--i}" actual | 
 | 	' | 
 | } | 
 |  | 
 | test_rebase success | 
 |  | 
 | test_expect_success 'with hook (cherry-pick)' ' | 
 | 	test_when_finished "git checkout -f main" && | 
 | 	git checkout -B other b && | 
 | 	git cherry-pick rebase-1 && | 
 | 	test "$(git log -1 --pretty=format:%s)" = "message (no editor)" | 
 | ' | 
 |  | 
 | test_expect_success 'with hook and editor (cherry-pick)' ' | 
 | 	test_when_finished "git checkout -f main" && | 
 | 	git checkout -B other b && | 
 | 	git cherry-pick -e rebase-1 && | 
 | 	test "$(git log -1 --pretty=format:%s)" = merge | 
 | ' | 
 |  | 
 | test_expect_success 'setup: commit-msg hook that always fails' ' | 
 | 	test_hook --setup --clobber prepare-commit-msg <<-\EOF | 
 | 	exit 1 | 
 | 	EOF | 
 | ' | 
 |  | 
 | test_expect_success 'with failing hook' ' | 
 |  | 
 | 	test_when_finished "git checkout -f main" && | 
 | 	head=$(git rev-parse HEAD) && | 
 | 	echo "more" >> file && | 
 | 	git add file && | 
 | 	test_must_fail env GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit -c $head | 
 |  | 
 | ' | 
 |  | 
 | test_expect_success 'with failing hook (--no-verify)' ' | 
 |  | 
 | 	test_when_finished "git checkout -f main" && | 
 | 	head=$(git rev-parse HEAD) && | 
 | 	echo "more" >> file && | 
 | 	git add file && | 
 | 	test_must_fail env GIT_EDITOR="\"\$FAKE_EDITOR\"" git commit --no-verify -c $head | 
 |  | 
 | ' | 
 |  | 
 | test_expect_success 'with failing hook (merge)' ' | 
 |  | 
 | 	test_when_finished "git checkout -f main" && | 
 | 	git checkout -B other HEAD@{1} && | 
 | 	echo "more" >> file && | 
 | 	git add file && | 
 | 	test_hook --remove prepare-commit-msg && | 
 | 	git commit -m other && | 
 | 	test_hook --setup prepare-commit-msg <<-\EOF && | 
 | 	exit 1 | 
 | 	EOF | 
 | 	git checkout - && | 
 | 	test_must_fail git merge --no-ff other | 
 |  | 
 | ' | 
 |  | 
 | test_expect_success 'with failing hook (cherry-pick)' ' | 
 | 	test_when_finished "git checkout -f main" && | 
 | 	git checkout -B other b && | 
 | 	test_must_fail git cherry-pick rebase-1 2>actual && | 
 | 	test $(grep -c prepare-commit-msg actual) = 1 | 
 | ' | 
 |  | 
 | test_done |