Subject: Re: [PATCH v4 1/2] negative-refspec: fix segfault on : refspec

From: Junio C Hamano <[email-masked]>
Date: Mon, 21 Dec 2020 18:28:54 -0800

Junio C Hamano <[email-masked]> writes:

> @@ -196,18 +201,27 @@ test_expect_success "push with matching : and negative refspec" '
>  	# We do not need test_config here as we are updating remote.one.push
>  	# again. The teardown of the first test_config will do --unset-all
>  	git -C two config --add remote.one.push ^refs/heads/master &&
> -	git -C two push one
> +
> +	# With "master" excluded, this push is a no-op.  Nothing gets
> +	# pushed and it succeeds.
> +	git -C two push -v one
>  '

Another obvious thing is that these tests will not work without
tweaking when merged to 'seen', as over there the name given by
default to the initial branch might not be 'master'.  The negative
refspec specification must be written in a way not to depend on
a particular name, I think.

Here is another try (disregard the previous one and squash this one
on top of your 1/2).

Thanks.

 t/t5582-fetch-negative-refspec.sh | 35 +++++++++++++++++++++++++++++------
 1 file changed, 29 insertions(+), 6 deletions(-)

diff --git c/t/t5582-fetch-negative-refspec.sh w/t/t5582-fetch-negative-refspec.sh
index a4960c586b..83a3c58c0c 100755
--- c/t/t5582-fetch-negative-refspec.sh
+++ w/t/t5582-fetch-negative-refspec.sh
@@ -187,27 +187,50 @@ test_expect_success "fetch --prune with negative refspec" '
 '
 
 test_expect_success "push with matching : and negative refspec" '
+	# For convenience, we use "master" to refer to the name of
+	# the branch created by default in the following.
+	#
+	# Repositories two and one have branches other than "master"
+	# but they have no overlap---"master" is the only one that
+	# is shared between them.  And the master branch at two is
+	# behind the master branch at one by one commit.
 	test_config -C two remote.one.push : &&
-	# Fails to push master w/ tip behind counterpart
+
+	# A matching push tries to update master, fails due to non-ff
 	test_must_fail git -C two push one &&
 
+	# "master" may actually not be "master"---find it out.
+	current=$(git symbolic-ref HEAD) &&
+
 	# If master is in negative refspec, then the command will not attempt
 	# to push and succeed.
 	# We do not need test_config here as we are updating remote.one.push
 	# again. The teardown of the first test_config will do --unset-all
-	git -C two config --add remote.one.push ^refs/heads/master &&
-	git -C two push one
+	git -C two config --add remote.one.push "^$current" &&
+
+	# With "master" excluded, this push is a no-op.  Nothing gets
+	# pushed and it succeeds.
+	git -C two push -v one
 '
 
 test_expect_success "push with matching +: and negative refspec" '
+	# The same set-up as above, whose side-effect was a no-op.
 	test_config -C two remote.one.push +: &&
-	# Fails to push master w/ tip behind counterpart
+
+	# The push refuses to update the "master" branch that is checked
+	# out in the "one" repository, even when it is forced with +:
 	test_must_fail git -C two push one &&
 
+	# "master" may actually not be "master"---find it out.
+	current=$(git symbolic-ref HEAD) &&
+
 	# If master is in negative refspec, then the command will not attempt
 	# to push and succeed
-	git -C two config --add remote.one.push ^refs/heads/master &&
-	git -C two push one
+	git -C two config --add remote.one.push "^$current" &&
+
+	# With "master" excluded, this push is a no-op.  Nothing gets
+	# pushed and it succeeds.
+	git -C two push -v one
 '
 
 test_done