diff mbox series

[v2,1/3] sequencer: comment checked-out branch properly

Message ID fc3b4438845e9fafd03fb608128099ce37ecd1b9.1731406513.git.code@khaugsbakk.name (mailing list archive)
State New
Headers show
Series sequencer: comment out properly in todo list | expand

Commit Message

Kristoffer Haugsbakk Nov. 12, 2024, 10:20 a.m. UTC
From: Kristoffer Haugsbakk <code@khaugsbakk.name>

`git rebase --update-ref` does not insert commands for dependent/sub-
branches which are checked out.[1]  Instead it leaves a comment about
that fact.  The comment char is hardcoded (#).  In turn the comment
line gets interpreted as an invalid command when `core.commentChar`
is in use.

† 1: 900b50c242 (rebase: add --update-refs option, 2022-07-19)

Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name>
---

Notes (series):
    v2:
    • Message: “hardcoded” (more common according to `git grep`)

 sequencer.c       |  5 +++--
 t/t3400-rebase.sh | 16 ++++++++++++++++
 2 files changed, 19 insertions(+), 2 deletions(-)

Comments

Junio C Hamano Nov. 13, 2024, 1:07 a.m. UTC | #1
kristofferhaugsbakk@fastmail.com writes:

> diff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh
> index 09f230eefb2..f61a717b190 100755
> --- a/t/t3400-rebase.sh
> +++ b/t/t3400-rebase.sh
> @@ -456,4 +456,20 @@ test_expect_success 'rebase when inside worktree subdirectory' '
>  	)
>  '
>  
> +test_expect_success 'git rebase --update-ref with core.commentChar and branch on worktree' '
> +	test_when_finished git branch -D base topic2 &&
> +	test_when_finished git checkout main &&
> +	test_when_finished git branch -D wt-topic &&
> +	test_when_finished git worktree remove wt-topic &&
> +	git checkout main &&
> +	git checkout -b base &&
> +	git checkout -b topic2 &&
> +	test_commit msg2 &&
> +	git worktree add wt-topic &&
> +	git checkout base &&
> +	test_commit msg3 &&
> +	git checkout topic2 &&
> +	git -c core.commentChar=% rebase --update-refs base
> +'

Can we improve this test a bit to give it more visibility into the
breakage?

I am sure that the internal machinery gets confused because it wants
to skip commented out lines assuming '%' is used for comments, and
fails to skip lines that are commented with '#', but it is a bit too
opaque how this would break without the fix.  Perhaps add a line or
two of a comment to the test to describe what the expected mode of
failure is?
Junio C Hamano Nov. 13, 2024, 1:18 a.m. UTC | #2
Junio C Hamano <gitster@pobox.com> writes:

> kristofferhaugsbakk@fastmail.com writes:
>
>> diff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh
>> index 09f230eefb2..f61a717b190 100755
>> --- a/t/t3400-rebase.sh
>> +++ b/t/t3400-rebase.sh
>> @@ -456,4 +456,20 @@ test_expect_success 'rebase when inside worktree subdirectory' '
>>  	)
>>  '
>>  
>> +test_expect_success 'git rebase --update-ref with core.commentChar and branch on worktree' '
>> +	test_when_finished git branch -D base topic2 &&
>> +	test_when_finished git checkout main &&
>> +	test_when_finished git branch -D wt-topic &&
>> +	test_when_finished git worktree remove wt-topic &&
>> +	git checkout main &&
>> +	git checkout -b base &&
>> +	git checkout -b topic2 &&
>> +	test_commit msg2 &&
>> +	git worktree add wt-topic &&
>> +	git checkout base &&
>> +	test_commit msg3 &&
>> +	git checkout topic2 &&
>> +	git -c core.commentChar=% rebase --update-refs base
>> +'
>
> Can we improve this test a bit to give it more visibility into the
> breakage?
>
> I am sure that the internal machinery gets confused because it wants
> to skip commented out lines assuming '%' is used for comments, and
> fails to skip lines that are commented with '#', but it is a bit too
> opaque how this would break without the fix.  Perhaps add a line or
> two of a comment to the test to describe what the expected mode of
> failure is?

Something like "a line commented-out with '#' in the list of
instructions used internally by "rebase" is not recognised as a
comment and you'd get an error that says '#' is not a valid
instruction", perhaps.
Phillip Wood Nov. 13, 2024, 2:47 p.m. UTC | #3
On 13/11/2024 01:07, Junio C Hamano wrote:
> kristofferhaugsbakk@fastmail.com writes:
> 
>> +test_expect_success 'git rebase --update-ref with core.commentChar and branch on worktree' '
>> +	test_when_finished git branch -D base topic2 &&
>> +	test_when_finished git checkout main &&
>> +	test_when_finished git branch -D wt-topic &&
>> +	test_when_finished git worktree remove wt-topic &&
>> +	git checkout main &&
>> +	git checkout -b base &&
>> +	git checkout -b topic2 &&
>> +	test_commit msg2 &&
>> +	git worktree add wt-topic &&
>> +	git checkout base &&
>> +	test_commit msg3 &&
>> +	git checkout topic2 &&
>> +	git -c core.commentChar=% rebase --update-refs base
>> +'
> 
> Can we improve this test a bit to give it more visibility into the
> breakage?
> 
> I am sure that the internal machinery gets confused because it wants
> to skip commented out lines assuming '%' is used for comments, and
> fails to skip lines that are commented with '#', but it is a bit too
> opaque how this would break without the fix.  Perhaps add a line or
> two of a comment to the test to describe what the expected mode of
> failure is?

Or check the todo list shown to the user with

	GIT_SEQUENCE_EDITOR="cat >actual" git -c core.commentChar=% \
		rebase -i --update-refs base &&
	test_grep "% Ref refs/heads/wt-topic checked out at " actual

so that we are sure that line exists - I had a quick look and I can't 
see any existing coverage checking that the todo list contains this comment.

Best Wishes

Phillip
Junio C Hamano Nov. 13, 2024, 10:57 p.m. UTC | #4
phillip.wood123@gmail.com writes:

>>> ...
>>> +	git checkout topic2 &&
>>> +	git -c core.commentChar=% rebase --update-refs base
>>> +'
>> Can we improve this test a bit to give it more visibility into the
>> breakage?
>> I am sure that the internal machinery gets confused because it wants
>> to skip commented out lines assuming '%' is used for comments, and
>> fails to skip lines that are commented with '#', but it is a bit too
>> opaque how this would break without the fix.  Perhaps add a line or
>> two of a comment to the test to describe what the expected mode of
>> failure is?
>
> Or check the todo list shown to the user with
>
> 	GIT_SEQUENCE_EDITOR="cat >actual" git -c core.commentChar=% \
> 		rebase -i --update-refs base &&
> 	test_grep "% Ref refs/heads/wt-topic checked out at " actual
>
> so that we are sure that line exists - I had a quick look and I can't
> see any existing coverage checking that the todo list contains this
> comment.

Yeah, with "rebase -i", it is a part of end-user experience to see
these comments, and a check to make sure they are shown to guide the
user is certainly a good idea.

A test of "rebase" without "-i" is a different matter.  Maybe in the
future, while we still reuse the machinery used for the interactive
mode to implement the non-interactive rebase, we may tweak it so
that we do not generate commented lines, only to be skipped by the
parser, in the todo list file that is only used internally.

Thanks.
diff mbox series

Patch

diff --git a/sequencer.c b/sequencer.c
index 353d804999b..1b6fd86f70b 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -6382,8 +6382,9 @@  static int add_decorations_to_list(const struct commit *commit,
 		/* If the branch is checked out, then leave a comment instead. */
 		if ((path = branch_checked_out(decoration->name))) {
 			item->command = TODO_COMMENT;
-			strbuf_addf(ctx->buf, "# Ref %s checked out at '%s'\n",
-				    decoration->name, path);
+			strbuf_commented_addf(ctx->buf, comment_line_str,
+					      "Ref %s checked out at '%s'\n",
+					      decoration->name, path);
 		} else {
 			struct string_list_item *sti;
 			item->command = TODO_UPDATE_REF;
diff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh
index 09f230eefb2..f61a717b190 100755
--- a/t/t3400-rebase.sh
+++ b/t/t3400-rebase.sh
@@ -456,4 +456,20 @@  test_expect_success 'rebase when inside worktree subdirectory' '
 	)
 '
 
+test_expect_success 'git rebase --update-ref with core.commentChar and branch on worktree' '
+	test_when_finished git branch -D base topic2 &&
+	test_when_finished git checkout main &&
+	test_when_finished git branch -D wt-topic &&
+	test_when_finished git worktree remove wt-topic &&
+	git checkout main &&
+	git checkout -b base &&
+	git checkout -b topic2 &&
+	test_commit msg2 &&
+	git worktree add wt-topic &&
+	git checkout base &&
+	test_commit msg3 &&
+	git checkout topic2 &&
+	git -c core.commentChar=% rebase --update-refs base
+'
+
 test_done