Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to detect whether a http git remote is smart or dumb?

Tags:

git

http

I'm implementing an option in my application to use --depth 1 to make a minimal functional clone of a git repo, and I've just realized that the dumb http transport doesn't support --depth. I'd like to automatically detect whether an http remote is dumb or smart so I can omit the --depth option when talking to dumb http repos. Is this possible?

Alternately, is there a direct way to check whether a git remote supports --depth?

like image 781
Ryan C. Thompson Avatar asked Feb 14 '12 01:02

Ryan C. Thompson


People also ask

Does Git use HTTP?

Git can use four distinct protocols to transfer data: Local, HTTP, Secure Shell (SSH) and Git.

What http smart?

Setting up Smart HTTP is basically just enabling a CGI script that is provided with Git called git-http-backend on the server. This CGI will read the path and headers sent by a git fetch or git push to an HTTP URL and determine if the client can communicate over HTTP (which is true for any client since version 1.6.

What is Git_url?

GIT_URL – the base name of the remote GIT repository. GIT_URL_N – if you are working with more than one remote Git repository (i.e n number of Git repositories) , this will list them all numerically. GIT_BRANCH – the name of the current Git branch the Jenkins Git plugin is operating upon.

What protocol does Git clone use?

The SSH Protocol Probably the most common transport protocol for Git is SSH. This is because SSH access to servers is already set up in most places — and if it isn't, it's easy to do. SSH is also the only network-based protocol that you can easily read from and write to.


2 Answers

One way is by direct HTTP queries.

Smart-supporting git clients add an argument to the end of the first URL grabbed, "[repo]/info/refs?service=git-upload-pack". A dumb server will just send "info/refs" file as text ignoring the argument, while a smart server will return some binary data in front of the refs list, including text "service=git-upload-pack" and a list of features (which you might be able to figure out "depth" support from).

You can script this smart/dumb test by using wget or curl to check the MIME type: text/plain (dumb) vs. application/x-git-upload-pack-advertisement (smart).

$ curl -si http://github.com/git/git.git/info/refs?service=git-upload-pack | grep --binary-files=text '^Content-Type'
Content-Type: application/x-git-upload-pack-advertisement
$ curl -si http://git.kernel.org/pub/scm/git/git.git/info/refs?service=git-upload-pack | grep --binary-files=text '^Content-Type'
Content-Type: application/x-git-upload-pack-advertisement
$ curl -si http://repo.or.cz/r/git.git/info/refs?service=git-upload-pack | grep --binary-files=text '^Content-Type'
Content-Type: text/plain

(Pipe to grep -q "^Content-Type: application/x-git" and use the return code for true/false test.)

like image 174
emsearcy Avatar answered Nov 16 '22 04:11

emsearcy


I believe since git 1.8.2, you can check the Content-Type header.
That is why commit git/git/4656bf47 mentions:

Before parsing a suspected smart-HTTP response verify the returned Content-Type matches the standard. This protects a client from attempting to process a payload that smells like a smart-HTTP server response.

You can see an example of setting that field in commit sitaramc/gitolite/32d14d39:

my $service = ( $ENV{SSH_ORIGINAL_COMMAND} =~ /git-receive-pack/ ? 'git-receive-pack' : 'git-upload-pack' );

if ($service) {
    print "Content-Type: application/x-$service-advertisement\r\n";
}

So a Content-Type header field with x-git-receive-pack-advertisement or x-git-upload-pack-advertisement means smart http.


Another way:

Before Git 2.26 (Q1 2020), "git fetch" over HTTP walker protocol did not show any progress output.

Now, we inherently do not know how much work remains, but still we can show something not to bore users.

See commit 7655b41 (03 Mar 2020) by René Scharfe (rscharfe).
(Merged by Junio C Hamano -- gitster -- in commit 4a5c3e1, 09 Mar 2020)

remote-curl: show progress for fetches over dumb HTTP

Signed-off-by: René Scharfe

Fetching over dumb HTTP transport doesn't show any progress, even with the option --progress.

If the connection is slow or there is a lot of data to get then this can take a long time while the user is left to wonder if git got stuck.

We don't know the number of objects to fetch at the outset, but we can count the ones we got.

Show an open-ended progress indicator based on that number if the user asked for it.

like image 25
VonC Avatar answered Nov 16 '22 03:11

VonC