"GOT", but the "O" is a cute, smiling sun Index | Thread

From:
Stefan Sperling <stsp@stsp.name>
Subject:
require space between commit author name and email
To:
gameoftrees@openbsd.org
Cc:
landry@openbsd.org
Date:
Mon, 31 Oct 2022 10:20:58 +0100

Download raw body.

Require space between commit author name and email, for Git compatibility.
 
Allowing such author fields breaks 'got send' towards Github for affected
commits because git-index-pack --strict will error out on the server:
 
$ git index-pack --strict pack-de791fb6a3a1961e44ac5d98d72fd533bf9277c8.pack
error: object 5d6bde9eaaf27f41ae8fa7112bb45e489d3c16b9: missingSpaceBeforeEmail:
    invalid author/committer line - missing space before email
fatal: fsck error in packed object

Problem encountered by landry@.

ok?
 
diff 15f404b1ceddb96797adc6a015786806435fc153 d30553f9a04931dcd98664630ecb04a318a69341
commit - 15f404b1ceddb96797adc6a015786806435fc153
commit + d30553f9a04931dcd98664630ecb04a318a69341
blob - 1ff53d9f2259c53d193902d67d5cbf3c5c1fd1c7
blob + d21399f4a8f84abbee2384d2577953581215edd6
--- got/got.c
+++ got/got.c
@@ -562,6 +562,9 @@ valid_author(const char *author)
 
 	while (*author && *author != '\n' && *author != '<' && *author != '>')
 		author++;
+	if (author != email && *author == '<' && *(author - 1) != ' ')
+		return got_error_fmt(GOT_ERR_COMMIT_BAD_AUTHOR, "%s: space "
+		    "between author name and email required", email);
 	if (*author++ != '<')
 		return got_error_fmt(GOT_ERR_COMMIT_NO_EMAIL, "%s", email);
 	while (*author && *author != '\n' && *author != '<' && *author != '>')
blob - f0c22e965e0b95671ae7f6667830714b714ecbe9
blob + bbfa823cda9c46a471aefb0a9263d11583de85b4
--- include/got_error.h
+++ include/got_error.h
@@ -181,6 +181,7 @@
 #define GOT_ERR_REFS_PROTECTED	163
 #define GOT_ERR_REF_PROTECTED	164
 #define GOT_ERR_REF_BUSY	165
+#define GOT_ERR_COMMIT_BAD_AUTHOR 166
 
 struct got_error {
         int code;
blob - d12ab759e6d259c67d2d70004b3aab5e63c0210c
blob + 3b3a634ed0c2f2b1d0dd925891e217c07e57cf5c
--- lib/error.c
+++ lib/error.c
@@ -231,6 +231,8 @@ static const struct got_error got_errors[] = {
 	{ GOT_ERR_REFS_PROTECTED, "reference namespace may not be modified" },
 	{ GOT_ERR_REF_PROTECTED," reference may not be modified" },
 	{ GOT_ERR_REF_BUSY, "reference cannot be updated; please try again" },
+	{ GOT_ERR_COMMIT_BAD_AUTHOR, "commit author formatting would "
+	    "make Git unhappy" },
 };
 
 static struct got_custom_error {
blob - d2688f0de1e8d3514a41b90c5ac5e0af154f5cbe
blob + bf310d5b1b095c5545625bae6cba5acc7abc8a66
--- regress/cmdline/commit.sh
+++ regress/cmdline/commit.sh
@@ -1681,7 +1681,44 @@ test_commit_gitignore() {
 	test_done "$testroot" "$ret"
 }
 
+test_commit_bad_author() {
+	local testroot=`test_init commit_bad_author`
 
+	got checkout $testroot/repo $testroot/wt > /dev/null
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		test_done "$testroot" $ret
+		return 1
+	fi
+
+	echo "modified alpha" > $testroot/wt/alpha
+
+	(cd $testroot/wt && got commit \
+		-A "${GIT_AUTHOR_NAME}<${GIT_AUTHOR_EMAIL}>" -m 'edit alpha') \
+		> /dev/null 2> $testroot/stderr
+	ret=$?
+	if [ $ret -eq 0 ]; then
+		test_done "$testroot" 1
+		return 1
+	fi
+
+	echo -n "got: ${GIT_AUTHOR_NAME}<${GIT_AUTHOR_EMAIL}>: " \
+	     > $testroot/stderr.expected
+	echo -n 'space between author name and email required: ' \
+	     >> $testroot/stderr.expected
+	echo 'commit author formatting would make Git unhappy' \
+		>> $testroot/stderr.expected
+	cmp -s $testroot/stderr.expected $testroot/stderr
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		diff -u $testroot/stderr.expected $testroot/stderr
+		test_done "$testroot" $ret
+		return 1
+	fi
+
+	test_done "$testroot" 0
+}
+
 test_parseargs "$@"
 run_test test_commit_basic
 run_test test_commit_new_subdir
@@ -1711,3 +1748,4 @@ run_test test_commit_gitignore
 run_test test_commit_prepared_logmsg
 run_test test_commit_large_file
 run_test test_commit_gitignore
+run_test test_commit_bad_author