Commit 787c8eb6b259591b756da4d79fa8f17a315a3710

Stefan Sperling 2019-07-11T22:40:44

fix extra whitespace in rebased log messages Trim leading and trailing whitespace from log messages when creating commits. Fixes a rebase issue but should be a good idea in general.

diff --git a/lib/object_create.c b/lib/object_create.c
index 5560dd3..eb00564 100644
--- a/lib/object_create.c
+++ b/lib/object_create.c
@@ -18,6 +18,7 @@
 #include <sys/stat.h>
 #include <sys/queue.h>
 
+#include <ctype.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <stdio.h>
@@ -320,11 +321,25 @@ got_object_commit_create(struct got_object_id **id,
 	size_t headerlen, len = 0, n;
 	FILE *commitfile = NULL;
 	struct got_object_qid *qid;
+	char *msg0, *msg;
 
 	*id = NULL;
 
 	SHA1Init(&sha1_ctx);
 
+	msg0 = strdup(logmsg);
+	if (msg0 == NULL)
+		return got_error_from_errno("strdup");
+	msg = msg0;
+
+	while (isspace(msg[0]))
+		msg++;
+	len = strlen(msg);
+	while (len > 0 && isspace(msg[len - 1])) {
+		msg[len - 1] = '\0';
+		len--;
+	}
+
 	if (asprintf(&author_str, "%s%s %lld +0000\n",
 	    GOT_COMMIT_LABEL_AUTHOR, author, author_time) == -1)
 		return got_error_from_errno("asprintf");
@@ -340,7 +355,7 @@ got_object_commit_create(struct got_object_id **id,
 	len = strlen(GOT_COMMIT_LABEL_TREE) + SHA1_DIGEST_STRING_LENGTH +
 	    nparents *
 	    (strlen(GOT_COMMIT_LABEL_PARENT) + SHA1_DIGEST_STRING_LENGTH) +
-	    + strlen(author_str) + strlen(committer_str) + 2 + strlen(logmsg);
+	    + strlen(author_str) + strlen(committer_str) + 2 + strlen(msg);
 
 	if (asprintf(&header, "%s %zd", GOT_OBJ_LABEL_COMMIT, len) == -1) {
 		err = got_error_from_errno("asprintf");
@@ -424,9 +439,9 @@ got_object_commit_create(struct got_object_id **id,
 		goto done;
 	}
 
-	len = strlen(logmsg);
-	SHA1Update(&sha1_ctx, logmsg, len);
-	n = fwrite(logmsg, 1, len, commitfile);
+	len = strlen(msg);
+	SHA1Update(&sha1_ctx, msg, len);
+	n = fwrite(msg, 1, len, commitfile);
 	if (n != len) {
 		err = got_ferror(commitfile, GOT_ERR_IO);
 		goto done;
@@ -454,6 +469,7 @@ got_object_commit_create(struct got_object_id **id,
 
 	err = create_object_file(*id, commitfile, repo);
 done:
+	free(msg0);
 	free(header);
 	free(tree_str);
 	free(author_str);
diff --git a/regress/cmdline/rebase.sh b/regress/cmdline/rebase.sh
index 7ea64d7..85d37b8 100755
--- a/regress/cmdline/rebase.sh
+++ b/regress/cmdline/rebase.sh
@@ -634,6 +634,63 @@ function test_rebase_path_prefix {
 	test_done "$testroot" "$ret"
 }
 
+function test_rebase_preserves_logmsg {
+	local testroot=`test_init rebase_preserves_logmsg`
+
+	(cd $testroot/repo && git checkout -q -b newbranch)
+	echo "modified delta on branch" > $testroot/repo/gamma/delta
+	git_commit $testroot/repo -m "modified delta on newbranch"
+
+	echo "modified alpha on branch" > $testroot/repo/alpha
+	git_commit $testroot/repo -m "modified alpha on newbranch"
+
+	(cd $testroot/repo && got log -c newbranch -l2 | grep -v ^date: \
+		> $testroot/log.expected)
+
+	local orig_commit1=`git_show_parent_commit $testroot/repo`
+	local orig_commit2=`git_show_head $testroot/repo`
+
+	(cd $testroot/repo && git checkout -q master)
+	echo "modified zeta on master" > $testroot/repo/epsilon/zeta
+	git_commit $testroot/repo -m "committing to zeta on master"
+	local master_commit=`git_show_head $testroot/repo`
+
+	got checkout $testroot/repo $testroot/wt > /dev/null
+	ret="$?"
+	if [ "$ret" != "0" ]; then
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+
+	(cd $testroot/wt && got rebase newbranch > /dev/null \
+		2> $testroot/stderr)
+
+	(cd $testroot/repo && git checkout -q newbranch)
+	local new_commit1=`git_show_parent_commit $testroot/repo`
+	local new_commit2=`git_show_head $testroot/repo`
+
+	echo -n > $testroot/stderr.expected
+	cmp -s $testroot/stderr.expected $testroot/stderr
+	ret="$?"
+	if [ "$ret" != "0" ]; then
+		diff -u $testroot/stderr.expected $testroot/stderr
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+
+	(cd $testroot/wt && got log -c newbranch -l2 | grep -v ^date: \
+		> $testroot/log)
+	sed -i -e "s/$orig_commit1/$new_commit1/" $testroot/log.expected
+	sed -i -e "s/$orig_commit2/$new_commit2/" $testroot/log.expected
+	cmp -s $testroot/log.expected $testroot/log
+	ret="$?"
+	if [ "$ret" != "0" ]; then
+		diff -u $testroot/log.expected $testroot/log
+	fi
+
+	test_done "$testroot" "$ret"
+}
+
 run_test test_rebase_basic
 run_test test_rebase_ancestry_check
 run_test test_rebase_continue
@@ -641,3 +698,4 @@ run_test test_rebase_abort
 run_test test_rebase_no_op_change
 run_test test_rebase_in_progress
 run_test test_rebase_path_prefix
+run_test test_rebase_preserves_logmsg