"GOT", but the "O" is a cute, smiling pufferfish. Index | Thread | Search

From:
Omar Polo <op@omarpolo.com>
Subject:
preventing non-sensical `mesg' in histedit
To:
gameoftrees@openbsd.org
Date:
Mon, 11 Jul 2022 21:12:48 +0200

Download raw body.

Thread
while talking on irc this issue pop up: there can be some strange
interactions between the commands in the histedit script.

while none of this is really surprising, preventing `mesg' in some
situations where the outcome is non-sensical.  In particular, a fold or
drop followed by a mesg.  (in the first case the commit would be first
reworded and then deleted, in the second case it would be reworded and
then the new text discarded by fold.)

so, the only valid options are pick -> mesg and edit -> mesg (which is
used by the regress test at least.)  It would be nice to prevent mesg ->
mesg too maybe.

diff below does this and adds a regress, ok?

diff /home/op/w/got
commit - c5d51f20832122bdce117ecbbe7dd460627531cf
path + /home/op/w/got
blob - 77ee3290c2b299ba86499c5b196115d3f54e96b6
file + got/got.c
--- got/got.c
+++ got/got.c
@@ -10702,7 +10702,7 @@ histedit_parse_list(struct got_histedit_list *histedit
 	int lineno = 0;
 	const struct got_histedit_cmd *cmd;
 	struct got_object_id *commit_id = NULL;
-	struct got_histedit_list_entry *hle = NULL;
+	struct got_histedit_list_entry *phle, *hle = NULL;
 
 	for (;;) {
 		len = getline(&line, &size, f);
@@ -10747,6 +10747,12 @@ histedit_parse_list(struct got_histedit_list *histedit
 				err = got_error(GOT_ERR_HISTEDIT_CMD);
 				break;
 			}
+			phle = TAILQ_LAST(histedit_cmds, got_histedit_list);
+			if (phle->cmd->code != GOT_HISTEDIT_PICK &&
+			    phle->cmd->code != GOT_HISTEDIT_EDIT) {
+				err = got_error(GOT_ERR_HISTEDIT_CMD);
+				break;
+			}
 			if (p[0] == '\0') {
 				err = histedit_edit_logmsg(hle, repo);
 				if (err)
blob - b15d00ef680f545b9c19d914b7c9d87cf23b1c8f
file + regress/cmdline/histedit.sh
--- regress/cmdline/histedit.sh
+++ regress/cmdline/histedit.sh
@@ -740,7 +740,6 @@ test_histedit_fold_last_commit() {
 
 	echo "pick $old_commit1" > $testroot/histedit-script
 	echo "fold $old_commit2" >> $testroot/histedit-script
-	echo "mesg committing folded changes" >> $testroot/histedit-script
 
 	(cd $testroot/wt && got histedit -F $testroot/histedit-script \
 		> $testroot/stdout 2> $testroot/stderr)
@@ -1973,6 +1972,100 @@ EOF
 	test_done "$testroot" $ret
 }
 
+test_histedit_mesg_invalid() {
+	local testroot=`test_init mesg_invalid`
+
+	local orig_commit=`git_show_head $testroot/repo`
+
+	echo "modified alpha on master" > $testroot/repo/alpha
+	(cd $testroot/repo && git rm -q beta)
+	echo "new file on master" > $testroot/repo/epsilon/new
+	(cd $testroot/repo && git add epsilon/new)
+	git_commit $testroot/repo -m 'committing changes'
+	local old_commit1=`git_show_head $testroot/repo`
+
+	echo "modified zeta on master" > $testroot/repo/epsilon/zeta
+	git_commit $testroot/repo -m 'committing to zeto on master'
+	local old_commit2=`git_show_head $testroot/repo`
+
+	got checkout -c $orig_commit $testroot/repo $testroot/wt > /dev/null
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		test_done "$testroot" $ret
+	fi
+
+	# try with a leading mesg
+
+	echo "mesg something something" > $testroot/histedit-script
+	echo "pick $old_commit1" >> $testroot/histedit-script
+	echo "pick $old_commit2" >> $testroot/histedit-script
+
+	(cd $testroot/wt && got histedit -F $testroot/histedit-script \
+		> $testroot/stdout 2> $testroot/stderr)
+	ret=$?
+	if [ $ret -eq 0 ]; then
+		echo "histedit succeeded unexpectedly" >&2
+		test_done "$testroot" 1
+		return 1
+	fi
+
+	echo "got: bad histedit command" > $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
+
+	# try again with drop -> mesg
+
+	echo "drop $old_commit1" > $testroot/histedit-script
+	echo "mesg something something" >> $testroot/histedit-script
+	echo "pick $old_commit2" >> $testroot/histedit-script
+
+	(cd $testroot/wt && got histedit -F $testroot/histedit-script \
+		> $testroot/stdout 2> $testroot/stderr)
+	ret=$?
+	if [ $ret -eq 0 ]; then
+		echo "histedit succeeded unexpectedly" >&2
+		test_done "$testroot" 1
+		return 1
+	fi
+
+	echo "got: bad histedit command" > $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
+
+	# try again with fold -> mesg
+
+	echo "fold $old_commit1" > $testroot/histedit-script
+	echo "mesg something something" >> $testroot/histedit-script
+	echo "pick $old_commit2" >> $testroot/histedit-script
+
+	(cd $testroot/wt && got histedit -F $testroot/histedit-script \
+		> $testroot/stdout 2> $testroot/stderr)
+	ret=$?
+	if [ $ret -eq 0 ]; then
+		echo "histedit succeeded unexpectedly" >&2
+		test_done "$testroot" 1
+		return 1
+	fi
+
+	echo "got: bad histedit command" > $testroot/stderr.expected
+	cmp -s $testroot/stderr.expected $testroot/stderr
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		diff -u $testroot/stderr.expected $testroot/stderr
+	fi
+	test_done "$testroot" $ret
+}
+
 test_parseargs "$@"
 run_test test_histedit_no_op
 run_test test_histedit_swap
@@ -1993,3 +2086,4 @@ run_test test_histedit_fold_only
 run_test test_histedit_fold_only_empty_logmsg
 run_test test_histedit_edit_only
 run_test test_histedit_prepend_line
+run_test test_histedit_mesg_invalid