Subject: Re: cannot clone --single-commit instead of --single-branch

From: Jonathan Nieder <[email-masked]>
Date: Thu, 1 Aug 2019 19:57:28 -0700

(cc: Duy, who might enjoy this walk through history)
Hi,

Alexander Mills wrote:

> git clone --single-branch=<sha>
>
> doesn't seem to work?

I've occasionally wanted something like this (actually, I've wanted to
pass a refname like "refs/meta/config").  builtin/clone.c contains

	static struct ref *find_remote_branch(const struct ref *refs, const char *branch)
	{
		struct ref *ref;
		struct strbuf head = STRBUF_INIT;
		strbuf_addstr(&head, "refs/heads/");
		strbuf_addstr(&head, branch);
		ref = find_ref_by_name(refs, head.buf);
		strbuf_release(&head);

		if (ref)
			return ref;

So far, what one would expect.

		strbuf_addstr(&head, "refs/tags/");
		strbuf_addstr(&head, branch);
		ref = find_ref_by_name(refs, head.buf);
		strbuf_release(&head);

Wait a second: a tag isn't a branch, so why do we accept it as a
value for --branch?  So this is stretching definitions a little
already.

"git log -L:find_remote_branch:builtin/clone.c" tells me this is from
v1.7.10-rc0~125^2~3 (clone: allow --branch to take a tag, 2012-01-16):

	Because a tag ref cannot be put to HEAD, HEAD will become detached.
	This is consistent with "git checkout <tag>".

I think ideally we could first check for a sha1 and then try the full
set of patterns from ref_rev_parse_rules.  What do you think?  Would
you be interested in taking a stab at it?

Thanks,
Jonathan