git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
* [PATCH 0/2] sequencer parsing fixes
@ 2023-02-23 20:54 Phillip Wood via GitGitGadget
  2023-02-23 20:55 ` [PATCH 1/2] rebase -i: match whole word in is_command() Phillip Wood via GitGitGadget
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Phillip Wood via GitGitGadget @ 2023-02-23 20:54 UTC (permalink / raw)
  To: git; +Cc: Johannes Schindelin, Phillip Wood

Fix a couple of small bugs in the parsing of todo lists

Phillip Wood (2):
  rebase -i: match whole word in is_command()
  rebase -i: fix parsing of "fixup -C<commit>"

 sequencer.c                     | 18 ++++++++----------
 t/lib-rebase.sh                 | 10 +++++++---
 t/t3404-rebase-interactive.sh   | 12 +++++++-----
 t/t3437-rebase-fixup-options.sh | 26 ++++++++++++++++++++++++++
 t/test-lib-functions.sh         |  8 ++++++++
 5 files changed, 56 insertions(+), 18 deletions(-)


base-commit: 06dd2baa8da4a73421b959ec026a43711b9d77f9
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1486%2Fphillipwood%2Fsequencer-parsing-fixes-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1486/phillipwood/sequencer-parsing-fixes-v1
Pull-Request: https://github.com/gitgitgadget/git/pull/1486
-- 
gitgitgadget

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 1/2] rebase -i: match whole word in is_command()
  2023-02-23 20:54 [PATCH 0/2] sequencer parsing fixes Phillip Wood via GitGitGadget
@ 2023-02-23 20:55 ` Phillip Wood via GitGitGadget
  2023-02-23 22:25   ` Junio C Hamano
  2023-02-26 10:29   ` Jeff King
  2023-02-23 20:55 ` [PATCH 2/2] rebase -i: fix parsing of "fixup -C<commit>" Phillip Wood via GitGitGadget
  2023-02-24 14:02 ` [PATCH 0/2] sequencer parsing fixes Johannes Schindelin
  2 siblings, 2 replies; 8+ messages in thread
From: Phillip Wood via GitGitGadget @ 2023-02-23 20:55 UTC (permalink / raw)
  To: git; +Cc: Johannes Schindelin, Phillip Wood, Phillip Wood

From: Phillip Wood <phillip.wood@dunelm.org.uk>

When matching an unabbreviated command is_command() only does a prefix
match which means it parses "pickled" as TODO_PICK. parse_insn_line()
does error out because is_command() only advances as far as the end of
"pick" so it looks like the command name is not followed by a space but
the error message is "missing arguments for pick" rather than telling
the user that the "pickled" is not a valid command.

Fix this by ensuring the match is follow by whitespace or the end of the
string as we already do for abbreviated commands. The (*bol = p) at the
end of the condition is a bit cute for my taste but I decided to leave
it be for now. Rather than add new tests the existing tests for bad
commands are adapted to use a bad command name that triggers the prefix
matching bug.

Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
---
 sequencer.c                   | 12 ++++++------
 t/lib-rebase.sh               |  2 +-
 t/t3404-rebase-interactive.sh | 12 +++++++-----
 3 files changed, 14 insertions(+), 12 deletions(-)

diff --git a/sequencer.c b/sequencer.c
index 65a34f9676c..d19ee189b57 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -2479,12 +2479,11 @@ static int is_command(enum todo_command command, const char **bol)
 {
 	const char *str = todo_command_info[command].str;
 	const char nick = todo_command_info[command].c;
-	const char *p = *bol + 1;
+	const char *p = *bol;
 
-	return skip_prefix(*bol, str, bol) ||
-		((nick && **bol == nick) &&
-		 (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r' || !*p) &&
-		 (*bol = p));
+	return (skip_prefix(p, str, &p) || (nick && *p++ == nick)) &&
+		(*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r' || !*p) &&
+		(*bol = p);
 }
 
 static int parse_insn_line(struct repository *r, struct todo_item *item,
@@ -2513,7 +2512,8 @@ static int parse_insn_line(struct repository *r, struct todo_item *item,
 			break;
 		}
 	if (i >= TODO_COMMENT)
-		return -1;
+		return error(_("invalid command '%.*s'"),
+			     (int)strcspn(bol, " \t\r\n"), bol);
 
 	/* Eat up extra spaces/ tabs before object name */
 	padding = strspn(bol, " \t");
diff --git a/t/lib-rebase.sh b/t/lib-rebase.sh
index b57541356bd..1d2f0429aea 100644
--- a/t/lib-rebase.sh
+++ b/t/lib-rebase.sh
@@ -60,7 +60,7 @@ set_fake_editor () {
 		">")
 			echo >> "$1";;
 		bad)
-			action="badcmd";;
+			action="pickled";;
 		fakesha)
 			test \& != "$action" || action=pick
 			echo "$action XXXXXXX False commit" >> "$1"
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index 462cefd25df..3862a4301a6 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -1449,14 +1449,15 @@ test_expect_success 'rebase --edit-todo respects rebase.missingCommitsCheck = ig
 
 test_expect_success 'rebase --edit-todo respects rebase.missingCommitsCheck = warn' '
 	cat >expect <<-EOF &&
-	error: invalid line 1: badcmd $(git rev-list --pretty=oneline --abbrev-commit -1 primary~4)
+	error: invalid command '\''pickled'\''
+	error: invalid line 1: pickled $(git rev-list --pretty=oneline --abbrev-commit -1 primary~4)
 	Warning: some commits may have been dropped accidentally.
 	Dropped commits (newer to older):
 	 - $(git rev-list --pretty=oneline --abbrev-commit -1 primary)
 	 - $(git rev-list --pretty=oneline --abbrev-commit -1 primary~4)
 	To avoid this message, use "drop" to explicitly remove a commit.
 	EOF
-	head -n4 expect >expect.2 &&
+	head -n5 expect >expect.2 &&
 	tail -n1 expect >>expect.2 &&
 	tail -n4 expect.2 >expect.3 &&
 	test_config rebase.missingCommitsCheck warn &&
@@ -1467,7 +1468,7 @@ test_expect_success 'rebase --edit-todo respects rebase.missingCommitsCheck = wa
 			git rebase -i --root &&
 		cp .git/rebase-merge/git-rebase-todo.backup orig &&
 		FAKE_LINES="2 3 4" git rebase --edit-todo 2>actual.2 &&
-		head -n6 actual.2 >actual &&
+		head -n7 actual.2 >actual &&
 		test_cmp expect actual &&
 		cp orig .git/rebase-merge/git-rebase-todo &&
 		FAKE_LINES="1 2 3 4" git rebase --edit-todo 2>actual.2 &&
@@ -1483,7 +1484,8 @@ test_expect_success 'rebase --edit-todo respects rebase.missingCommitsCheck = wa
 
 test_expect_success 'rebase --edit-todo respects rebase.missingCommitsCheck = error' '
 	cat >expect <<-EOF &&
-	error: invalid line 1: badcmd $(git rev-list --pretty=oneline --abbrev-commit -1 primary~4)
+	error: invalid command '\''pickled'\''
+	error: invalid line 1: pickled $(git rev-list --pretty=oneline --abbrev-commit -1 primary~4)
 	Warning: some commits may have been dropped accidentally.
 	Dropped commits (newer to older):
 	 - $(git rev-list --pretty=oneline --abbrev-commit -1 primary)
@@ -1583,7 +1585,7 @@ test_expect_success 'static check of bad command' '
 		set_fake_editor &&
 		test_must_fail env FAKE_LINES="1 2 3 bad 4 5" \
 		git rebase -i --root 2>actual &&
-		test_i18ngrep "badcmd $(git rev-list --oneline -1 primary~1)" \
+		test_i18ngrep "pickled $(git rev-list --oneline -1 primary~1)" \
 				actual &&
 		test_i18ngrep "You can fix this with .git rebase --edit-todo.." \
 				actual &&
-- 
gitgitgadget


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 2/2] rebase -i: fix parsing of "fixup -C<commit>"
  2023-02-23 20:54 [PATCH 0/2] sequencer parsing fixes Phillip Wood via GitGitGadget
  2023-02-23 20:55 ` [PATCH 1/2] rebase -i: match whole word in is_command() Phillip Wood via GitGitGadget
@ 2023-02-23 20:55 ` Phillip Wood via GitGitGadget
  2023-02-23 22:35   ` Junio C Hamano
  2023-02-24 14:02 ` [PATCH 0/2] sequencer parsing fixes Johannes Schindelin
  2 siblings, 1 reply; 8+ messages in thread
From: Phillip Wood via GitGitGadget @ 2023-02-23 20:55 UTC (permalink / raw)
  To: git; +Cc: Johannes Schindelin, Phillip Wood, Phillip Wood

From: Phillip Wood <phillip.wood@dunelm.org.uk>

If the user omits the space between "-C" and the commit in a fixup
command then it is parsed as an ordinary fixup and the commit message is
not updated as it should be. Fix this by making the space between "-C"
and "<commit>" optional as it is for the "merge" command.

Note that set_replace_editor() is changed to set $GIT_SEQUENCE_EDITOR
instead of $EDITOR in order to be able to replace the todo list and
reword commits with $FAKE_COMMIT_MESSAGE. This is safe as all the
existing users are using set_replace_editor() to replace the todo list.

Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
---
 sequencer.c                     |  6 ++----
 t/lib-rebase.sh                 |  8 ++++++--
 t/t3437-rebase-fixup-options.sh | 26 ++++++++++++++++++++++++++
 t/test-lib-functions.sh         |  8 ++++++++
 4 files changed, 42 insertions(+), 6 deletions(-)

diff --git a/sequencer.c b/sequencer.c
index d19ee189b57..9ddae1ce944 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -2542,12 +2542,10 @@ static int parse_insn_line(struct repository *r, struct todo_item *item,
 	}
 
 	if (item->command == TODO_FIXUP) {
-		if (skip_prefix(bol, "-C", &bol) &&
-		   (*bol == ' ' || *bol == '\t')) {
+		if (skip_prefix(bol, "-C", &bol)) {
 			bol += strspn(bol, " \t");
 			item->flags |= TODO_REPLACE_FIXUP_MSG;
-		} else if (skip_prefix(bol, "-c", &bol) &&
-				  (*bol == ' ' || *bol == '\t')) {
+		} else if (skip_prefix(bol, "-c", &bol)) {
 			bol += strspn(bol, " \t");
 			item->flags |= TODO_EDIT_FIXUP_MSG;
 		}
diff --git a/t/lib-rebase.sh b/t/lib-rebase.sh
index 1d2f0429aea..7ca5b918f04 100644
--- a/t/lib-rebase.sh
+++ b/t/lib-rebase.sh
@@ -211,6 +211,9 @@ check_reworded_commits () {
 # usage: set_replace_editor <file>
 #
 # Replace the todo file with the exact contents of the given file.
+# N.B. sets GIT_SEQUENCE_EDITOR rather than EDITOR so it can be
+# combined with set_fake_editor to reword commits and replace the
+# todo list
 set_replace_editor () {
 	cat >script <<-\EOF &&
 	cat FILENAME >"$1"
@@ -219,6 +222,7 @@ set_replace_editor () {
 	cat "$1"
 	EOF
 
-	sed -e "s/FILENAME/$1/g" <script | write_script fake-editor.sh &&
-	test_set_editor "$(pwd)/fake-editor.sh"
+	sed -e "s/FILENAME/$1/g" script |
+		write_script fake-sequence-editor.sh &&
+	test_set_sequence_editor "$(pwd)/fake-sequence-editor.sh"
 }
diff --git a/t/t3437-rebase-fixup-options.sh b/t/t3437-rebase-fixup-options.sh
index 274699dadb8..dd3b301fa7a 100755
--- a/t/t3437-rebase-fixup-options.sh
+++ b/t/t3437-rebase-fixup-options.sh
@@ -51,6 +51,7 @@ test_expect_success 'setup' '
 	body
 	EOF
 
+	test_commit initial &&
 	test_commit A A &&
 	test_commit B B &&
 	get_author HEAD >expected-author &&
@@ -209,4 +210,29 @@ test_expect_success 'fixup -C works upon --autosquash with amend!' '
 		actual-squash-message
 '
 
+test_expect_success 'fixup -[Cc]<commit> works' '
+	test_when_finished "test_might_fail git rebase --abort" &&
+	cat >todo <<-\EOF &&
+	pick A
+	fixup -CA1
+	pick B
+	fixup -cA2
+	EOF
+	(
+		set_replace_editor todo &&
+		FAKE_COMMIT_MESSAGE="edited and fixed up" \
+			git rebase -i initial initial
+	) &&
+	git log --pretty=format:%B initial.. >actual &&
+	cat >expect <<-EOF &&
+	edited and fixed up
+	$EMPTY
+	new subject
+	$EMPTY
+	new
+	body
+	EOF
+	test_cmp expect actual
+'
+
 test_done
diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
index 58cfd2f1fda..999d46fafe7 100644
--- a/t/test-lib-functions.sh
+++ b/t/test-lib-functions.sh
@@ -32,6 +32,14 @@ test_set_editor () {
 	export EDITOR
 }
 
+# Like test_set_editor but sets GIT_SEQUENCE_EDITOR instead of EDITOR
+test_set_sequence_editor () {
+	FAKE_SEQUENCE_EDITOR="$1"
+	export FAKE_SEQUENCE_EDITOR
+	GIT_SEQUENCE_EDITOR='"$FAKE_SEQUENCE_EDITOR"'
+	export GIT_SEQUENCE_EDITOR
+}
+
 test_decode_color () {
 	awk '
 		function name(n) {
-- 
gitgitgadget

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/2] rebase -i: match whole word in is_command()
  2023-02-23 20:55 ` [PATCH 1/2] rebase -i: match whole word in is_command() Phillip Wood via GitGitGadget
@ 2023-02-23 22:25   ` Junio C Hamano
  2023-02-26 10:29   ` Jeff King
  1 sibling, 0 replies; 8+ messages in thread
From: Junio C Hamano @ 2023-02-23 22:25 UTC (permalink / raw)
  To: Phillip Wood via GitGitGadget; +Cc: git, Johannes Schindelin, Phillip Wood

"Phillip Wood via GitGitGadget" <gitgitgadget@gmail.com> writes:

>  	const char *str = todo_command_info[command].str;
>  	const char nick = todo_command_info[command].c;
> -	const char *p = *bol + 1;
> +	const char *p = *bol;
>  
> -	return skip_prefix(*bol, str, bol) ||
> -		((nick && **bol == nick) &&
> -		 (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r' || !*p) &&
> -		 (*bol = p));
> +	return (skip_prefix(p, str, &p) || (nick && *p++ == nick)) &&
> +		(*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r' || !*p) &&
> +		(*bol = p);

OK.  So we skip the command name string in the line given by the
end-user (or see if the first letter matches the single letter
command) and make sure it is followed by a whitespace or EOL in
either case.  The old code was not doing the "end of word" check
for the longhand at all, which was clearly wrong.

I too find "&& (*bol = p)" that pretends to be a Boolean condition
but is there only for its side effect distasteful, but I agree with
you that fixing it is outside the scope of this patch.

> @@ -2513,7 +2512,8 @@ static int parse_insn_line(struct repository *r, struct todo_item *item,
>  			break;
>  		}
>  	if (i >= TODO_COMMENT)
> -		return -1;
> +		return error(_("invalid command '%.*s'"),
> +			     (int)strcspn(bol, " \t\r\n"), bol);

Nice.

> diff --git a/t/lib-rebase.sh b/t/lib-rebase.sh
> index b57541356bd..1d2f0429aea 100644
> --- a/t/lib-rebase.sh
> +++ b/t/lib-rebase.sh
> @@ -60,7 +60,7 @@ set_fake_editor () {
>  		">")
>  			echo >> "$1";;
>  		bad)
> -			action="badcmd";;
> +			action="pickled";;

;-)

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 2/2] rebase -i: fix parsing of "fixup -C<commit>"
  2023-02-23 20:55 ` [PATCH 2/2] rebase -i: fix parsing of "fixup -C<commit>" Phillip Wood via GitGitGadget
@ 2023-02-23 22:35   ` Junio C Hamano
  0 siblings, 0 replies; 8+ messages in thread
From: Junio C Hamano @ 2023-02-23 22:35 UTC (permalink / raw)
  To: Phillip Wood via GitGitGadget; +Cc: git, Johannes Schindelin, Phillip Wood

"Phillip Wood via GitGitGadget" <gitgitgadget@gmail.com> writes:

>  	if (item->command == TODO_FIXUP) {
> -		if (skip_prefix(bol, "-C", &bol) &&
> -		   (*bol == ' ' || *bol == '\t')) {
> +		if (skip_prefix(bol, "-C", &bol)) {
>  			bol += strspn(bol, " \t");
>  			item->flags |= TODO_REPLACE_FIXUP_MSG;

OK.  An explicit check followed by strspn() is an odd way to write
this even if it meant to require at least one whitespace, but I
agree that this one probably did not even mean to require a
whitespace there, and the updated code looks much easier to read.

> diff --git a/t/lib-rebase.sh b/t/lib-rebase.sh
> index 1d2f0429aea..7ca5b918f04 100644
> --- a/t/lib-rebase.sh
> +++ b/t/lib-rebase.sh
> ...
> +test_expect_success 'fixup -[Cc]<commit> works' '
> +	test_when_finished "test_might_fail git rebase --abort" &&
> +	cat >todo <<-\EOF &&
> +	pick A
> +	fixup -CA1
> +	pick B
> +	fixup -cA2
> +	EOF

By the way, this is much easier to follow, than the todo file written
in the ugly FAKE_LINES language, to see what is being tested.

Will queue.  Thanks.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 0/2] sequencer parsing fixes
  2023-02-23 20:54 [PATCH 0/2] sequencer parsing fixes Phillip Wood via GitGitGadget
  2023-02-23 20:55 ` [PATCH 1/2] rebase -i: match whole word in is_command() Phillip Wood via GitGitGadget
  2023-02-23 20:55 ` [PATCH 2/2] rebase -i: fix parsing of "fixup -C<commit>" Phillip Wood via GitGitGadget
@ 2023-02-24 14:02 ` Johannes Schindelin
  2023-02-24 17:03   ` Junio C Hamano
  2 siblings, 1 reply; 8+ messages in thread
From: Johannes Schindelin @ 2023-02-24 14:02 UTC (permalink / raw)
  To: Phillip Wood via GitGitGadget; +Cc: git, Phillip Wood

Hi Phillip,

On Thu, 23 Feb 2023, Phillip Wood via GitGitGadget wrote:

> Fix a couple of small bugs in the parsing of todo lists

Thank you, those fixes look quite good to me.

Ciao,
Johannes

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 0/2] sequencer parsing fixes
  2023-02-24 14:02 ` [PATCH 0/2] sequencer parsing fixes Johannes Schindelin
@ 2023-02-24 17:03   ` Junio C Hamano
  0 siblings, 0 replies; 8+ messages in thread
From: Junio C Hamano @ 2023-02-24 17:03 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: Phillip Wood via GitGitGadget, git, Phillip Wood

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:

> Hi Phillip,
>
> On Thu, 23 Feb 2023, Phillip Wood via GitGitGadget wrote:
>
>> Fix a couple of small bugs in the parsing of todo lists
>
> Thank you, those fixes look quite good to me.

Thanks, both.  Let's merge them down quickly.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/2] rebase -i: match whole word in is_command()
  2023-02-23 20:55 ` [PATCH 1/2] rebase -i: match whole word in is_command() Phillip Wood via GitGitGadget
  2023-02-23 22:25   ` Junio C Hamano
@ 2023-02-26 10:29   ` Jeff King
  1 sibling, 0 replies; 8+ messages in thread
From: Jeff King @ 2023-02-26 10:29 UTC (permalink / raw)
  To: Phillip Wood via GitGitGadget; +Cc: git, Johannes Schindelin, Phillip Wood

On Thu, Feb 23, 2023 at 08:55:00PM +0000, Phillip Wood via GitGitGadget wrote:

> Fix this by ensuring the match is follow by whitespace or the end of the
> string as we already do for abbreviated commands. The (*bol = p) at the
> end of the condition is a bit cute for my taste but I decided to leave
> it be for now. Rather than add new tests the existing tests for bad
> commands are adapted to use a bad command name that triggers the prefix
> matching bug.

FWIW, coverity complained about the (*bol = p) assignment in the
conditional, since "p" must be non-NULL at this point.

So this is email is a combination of:

  - a data point that it is not just you that finds it a bit cute (in
    case you do want to change it later); and

  - a hearty thank you for mentioning it in the commit message, since
    just looking at the code left me scratching my head at whether this
    was a bug.

-Peff

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2023-02-26 10:29 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-02-23 20:54 [PATCH 0/2] sequencer parsing fixes Phillip Wood via GitGitGadget
2023-02-23 20:55 ` [PATCH 1/2] rebase -i: match whole word in is_command() Phillip Wood via GitGitGadget
2023-02-23 22:25   ` Junio C Hamano
2023-02-26 10:29   ` Jeff King
2023-02-23 20:55 ` [PATCH 2/2] rebase -i: fix parsing of "fixup -C<commit>" Phillip Wood via GitGitGadget
2023-02-23 22:35   ` Junio C Hamano
2023-02-24 14:02 ` [PATCH 0/2] sequencer parsing fixes Johannes Schindelin
2023-02-24 17:03   ` Junio C Hamano

Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).