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

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?

  • Opposite of `git push --mirror`? How do I get my repo back?
  • Pod from github not working
  • Git log stats with regular expressions
  • pip install a local git repository
  • Can i set up SourceTree as external tool in Visual Studio to view log for current file?
  • git, github remembers wrong account
  • “fatal: corrupt patch at line XX” when staging single line
  • Passwords in git tree + Heroku + Github
  • using git to maintain a shared codebase
  • How to edit Git “add patch” hunks/diffs/lines during selective staging?
  • Structuring Go subpackages for teams
  • Is any body making a windows replacement to msysgit with libgit2,libgit2sharp, Ngit?
  • 2 Solutions collect form web for “Is it possible to detect whether a http git remote is smart or dumb?”

    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.)

    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.

    Git Baby is a git and github fan, let's start git clone.