git ls-remote
works by fetching the full list of refs from the remote and then filtering it locally:
int cmd_ls_remote(int argc, const char **argv, const char *prefix)
{
...
transport = transport_get(remote, NULL);
if (uploadpack != NULL)
transport_set_option(transport, TRANS_OPT_UPLOADPACK, uploadpack);
/* Get all refs from the remote */
ref = transport_get_remote_refs(transport);
if (transport_disconnect(transport))
return 1;
if (!dest && !quiet)
fprintf(stderr, "From %s\n", *remote->url);
/* Filter the list of all refs */
for ( ; ref; ref = ref->next) {
if (!check_ref_type(ref, flags))
continue;
if (!tail_match(pattern, ref->name))
continue;
if (show_symref_target && ref->symref)
printf("ref: %s\t%s\n", ref->symref, ref->name);
printf("%s\t%s\n", oid_to_hex(&ref->old_oid), ref->name);
status = 0; /* we found something */
}
return status;
}
UPDATE
According to this page, explaining git transfer protocols, if the remote supports the dumb protocol, then you can obtain the remote refs/heads/branchname
file directly (e.g. using curl
).
The Dumb Protocol
If you’re setting up a repository to be served read-only over HTTP, the dumb protocol is likely what will be used. This protocol is called “dumb” because it requires no Git-specific code on the server side during the transport process; the fetch process is a series of HTTP GET requests, where the client can assume the layout of the Git repository on the server.
...
Otherwise, when the smart protocol is utilized, the first piece of data sent from a remote is always the list of all remote references, i.e. any git command connecting to a remote via the smart protocol acts as if git ls-remote
is run internally (more technically, all such commands call the transport_get_remote_refs()
function). In that case, unfortunately, there is no way to speed-up your query, not even a workaround.
The Smart Protocol
...
Uploading Data
To upload data to a remote process, Git uses the send-pack
and receive-pack
processes. The send-pack
process runs on the client and connects to a receive-pack
process on the remote side.
...
The git-receive-pack
command immediately responds with one line for
each reference it currently has.
...
Downloading Data
When you download data, the fetch-pack
and upload-pack
processes
are involved. The client initiates a fetch-pack
process that
connects to an upload-pack
process on the remote side to negotiate
what data will be transferred down.
...
After fetch-pack
connects, upload-pack
sends back something like
this: ... This is very similar to what receive-pack
responds with, but
the capabilities are different (i.e. the list of all refs + some
additional data).
...