git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Junio C Hamano <gitster@pobox.com>
To: Matt McCutchen <matt@mattmccutchen.net>
Cc: git@vger.kernel.org
Subject: Re: [PATCH] fetch: print an error when declining to request an unadvertised object
Date: Fri, 10 Feb 2017 10:36:12 -0800	[thread overview]
Message-ID: <xmqqwpcxlwpv.fsf@gitster.mtv.corp.google.com> (raw)
In-Reply-To: <1486747828.17272.5.camel@mattmccutchen.net> (Matt McCutchen's message of "Fri, 10 Feb 2017 12:26:33 -0500")

Matt McCutchen <matt@mattmccutchen.net> writes:

> Currently "git fetch REMOTE SHA1" silently exits 1 if the server doesn't
> allow requests for unadvertised objects by sha1.  Change it to print a
> meaningful error message.
>
> Signed-off-by: Matt McCutchen <matt@mattmccutchen.net>
> ---
>
> The fetch code looks unbelievably complicated to me and I don't understand all
> the cases that can arise.  Hopefully this patch is an acceptable solution to the
> problem.

At first I thought that this should be caught on the sending end
(grep for "not our ref" in upload-pack.c), but you found a case
where we do not even ask the sender on the requesting side.

I am not convinced that modifying filter_refs() is needed or even
desirable, though.

There is this piece of code near the end of builtin/fetch-pack.c:

	/*
	 * If the heads to pull were given, we should have consumed
	 * all of them by matching the remote.  Otherwise, 'git fetch
	 * remote no-such-ref' would silently succeed without issuing
	 * an error.
	 */
	for (i = 0; i < nr_sought; i++) {
		if (!sought[i] || sought[i]->matched)
			continue;
		error("no such remote ref %s", sought[i]->name);
		ret = 1;
	}

that happens before the command shows the list of fetched refs, and
this code is prepared to inspect what happend to the requests it (in
response to the user request) made to the underlying fetch
machinery, and issue the error message.
If you change your command line to "git fetch-pack REMOTE SHA1", you
do see an error from the above.

That is a good indication that the underlying fetch machinery called
by this caller is already doing diagnosis that is necessary for the
caller to issue such an error.  So why do we fail to say anything in
"git fetch"?

I think the real issue is that when fetch-pack machinery is used via
the transport layer, the transport layer discards the information on
these original request (i.e. what is returned in sought[]).

Instead, the caller of the fetch-pack machinery receives the list of
filtered refs as the return value of fetch_pack() function, and only
looks at "refs" without checking what happened to the original
request to_fetch[] (which corresponds to sought[] in the fetch-pack
command).  This all happens in transport.c::fetch_refs_via_pack().
I think that function is a much better place to error or die than
filter_refs().


>  fetch-pack.c          | 31 ++++++++++++++++---------------
>  t/t5516-fetch-push.sh |  3 ++-
>  2 files changed, 18 insertions(+), 16 deletions(-)
>
> diff --git a/fetch-pack.c b/fetch-pack.c
> index 601f077..117874c 100644
> --- a/fetch-pack.c
> +++ b/fetch-pack.c
> @@ -598,23 +598,24 @@ static void filter_refs(struct fetch_pack_args *args,
>  	}
>  
>  	/* Append unmatched requests to the list */
> -	if ((allow_unadvertised_object_request &
> -	    (ALLOW_TIP_SHA1 | ALLOW_REACHABLE_SHA1))) {
> -		for (i = 0; i < nr_sought; i++) {
> -			unsigned char sha1[20];
> +	for (i = 0; i < nr_sought; i++) {
> +		unsigned char sha1[20];
>  
> -			ref = sought[i];
> -			if (ref->matched)
> -				continue;
> -			if (get_sha1_hex(ref->name, sha1) ||
> -			    ref->name[40] != '\0' ||
> -			    hashcmp(sha1, ref->old_oid.hash))
> -				continue;
> +		ref = sought[i];
> +		if (ref->matched)
> +			continue;
> +		if (get_sha1_hex(ref->name, sha1) ||
> +		    ref->name[40] != '\0' ||
> +		    hashcmp(sha1, ref->old_oid.hash))
> +			continue;
>  
> -			ref->matched = 1;
> -			*newtail = copy_ref(ref);
> -			newtail = &(*newtail)->next;
> -		}
> +		if (!(allow_unadvertised_object_request &
> +		    (ALLOW_TIP_SHA1 | ALLOW_REACHABLE_SHA1)))
> +			die(_("Server does not allow request for unadvertised object %s"), ref->name);
> +
> +		ref->matched = 1;
> +		*newtail = copy_ref(ref);
> +		newtail = &(*newtail)->next;
>  	}
>  	*refs = newlist;
>  }
> diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
> index 0fc5a7c..177897e 100755
> --- a/t/t5516-fetch-push.sh
> +++ b/t/t5516-fetch-push.sh
> @@ -1098,7 +1098,8 @@ test_expect_success 'fetch exact SHA1' '
>  		test_must_fail git cat-file -t $the_commit &&
>  
>  		# fetching the hidden object should fail by default
> -		test_must_fail git fetch -v ../testrepo $the_commit:refs/heads/copy &&
> +		test_must_fail git fetch -v ../testrepo $the_commit:refs/heads/copy 2>err &&
> +		test_i18ngrep "Server does not allow request for unadvertised object" err &&
>  		test_must_fail git rev-parse --verify refs/heads/copy &&
>  
>  		# the server side can allow it to succeed

  reply	other threads:[~2017-02-10 18:37 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-02-10 17:26 [PATCH] fetch: print an error when declining to request an unadvertised object Matt McCutchen
2017-02-10 18:36 ` Junio C Hamano [this message]
2017-02-12 21:13   ` Matt McCutchen
2017-02-12 23:49     ` Junio C Hamano
2017-02-19  1:55       ` Matt McCutchen
2017-02-21  6:36         ` Junio C Hamano
2017-02-22 16:01           ` [PATCH 1/3] fetch-pack: move code to report unmatched refs to a function Matt McCutchen
2017-02-22 17:11             ` Junio C Hamano
2017-02-22 16:01               ` [PATCH v2 " Matt McCutchen
2017-02-22 16:02               ` [PATCH v2 2/3] fetch_refs_via_pack: call report_unmatched_refs Matt McCutchen
2017-02-22 16:05               ` [PATCH v2 3/3] fetch-pack: add specific error for fetching an unadvertised object Matt McCutchen
2017-02-22 17:26               ` [PATCH 1/3] fetch-pack: move code to report unmatched refs to a function Matt McCutchen
2017-02-22 16:02           ` [PATCH 2/3] fetch_refs_via_pack: call report_unmatched_refs Matt McCutchen
2017-02-22 16:05           ` [PATCH 3/3] fetch-pack: add specific error for fetching an unadvertised object Matt McCutchen
2017-02-22 16:17           ` [PATCH] fetch: print an error when declining to request " Matt McCutchen
2017-02-22 17:07             ` Junio C Hamano
2017-02-19  2:07       ` Matt McCutchen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=xmqqwpcxlwpv.fsf@gitster.mtv.corp.google.com \
    --to=gitster@pobox.com \
    --cc=git@vger.kernel.org \
    --cc=matt@mattmccutchen.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).