Subject: Re: [PATCH v4 12/20] t: refactor tests depending on Perl to print data

From: Junio C Hamano <[email-masked]>
Date: Tue, 10 Jun 2025 14:31:34 -0700

SZEDER Gábor <[email-masked]> writes:

>> -	perl -lpe "
>> -		if (/^From:/) {
>> +	awk "
>> +		/^From:/{
>>  			print \"From: x <x\@example.com>\";
>>  			print \"Date: Sat, 1 Jan 2000 00:00:00 +0000\";
>>  			print \"Subject: x\n\";
>> -		}
>> -	" patch >msg &&
>> +		}; 1
>> +	" <patch >msg &&
>
> With the conversion to awk I get the following warning from gawk:
>
>   awk: cmd. line:3: warning: escape sequence `\@' treated as plain `@'

Thanks for noticing.

The backslash protecting the array @example from getting referenced
can safely be removed, as "@" in string means nothing special here,
unlike in the original in Perl.

>> @@ -241,8 +234,7 @@ test_expect_success 'pseudo-merge pattern with capture groups' '
>>  			test_commit_bulk 16 &&
>>  
>>  			git rev-list HEAD~16.. >in &&
>> -
>> -			perl -lne "print \"create refs/remotes/$r/tags/\$. \$_\"" <in |
>> +			sed "s|\(.*\)|create refs/remotes/$r/tags/\1 \1" in |
>
> This conversion results in the error:
>
>   sed: -e expression #1, char 41: unterminated `s' command

This not just misses the terminating "|", but the conversion seems
not very faithful to the original.  It used to create tags 1 2 3 4
5... but now the tags it tries to create (unsuccessfully) are the
names of tagged objects in full hexadecimal glory.

> I find it suspicious that the test still succeeds...

That is because the downstream "update-ref --stdin" does not notice
anything wrong in its input, which is empty.

>>  			git update-ref --stdin || return 1
>>  		done &&

And the step after this, which is not touched by this patch, may not
be testing what it wants to test.  test_pseudo_merges produces no
lines, and iterating over the lines in that file produces an empty
result in "remotes" below ...

>> @@ -258,7 +250,7 @@ test_expect_success 'pseudo-merge pattern with capture groups' '
>>  		do
>>  			test_pseudo_merge_commits $m >oids &&
>>  			grep -f oids refs |
>> -			perl -lne "print \$1 if /refs\/remotes\/([0-9]+)/" |
>> +			sed -n "s|refs/remotes/\([0-9][0-9]*\)/|\1|p" &&
>>  			sort -u || return 1
>>  		done >remotes &&

... and then it checks remotes has no duplicated lines with

		test $(wc -l <remotes) -eq $(sort -u <remotes | wc -l)

No wonder it passes, as remotes is an empty file ;-)