Finding out the version of git on remote server
Modern git servers (beginning in git 1.7.12.1) will return their version information in the capabilities negotiation in the protocol. While it's accurate that there's no git command that you can run locally, you can simply query the git server for the information and a recent version will provide the version number.
You can find this information using HTTPS or SSH.
HTTPS
You can use a web client to request:
<repository url>/info/refs?service=git-upload-pack
And examine the first line for the agent=
report.
For example, against CodePlex:
% curl https://git01.codeplex.com/gittf/info/refs\?service=git-upload-pack
000000bd43569b9f6f29136b6544809eacd2417a308f9341 HEAD\0multi_ack thin-pack
side-band side-band-64k ofs-delta shallow no-progress include-tag multi_ack_detailed
no-done agent=git/1.8.4.msysgit.0
Which indicates that CodePlex is using Git for Windows 1.8.4 (git/1.8.4.msysgit.0
).
Or against GitHub:
% curl https://github.com/libgit2/libgit2.git/info/refs\?service=git-upload-pack
000000f83f8d005a82b39c504220d65b6a6aa696c3b1a9c4 HEAD\0multi_ack
thin-pack side-band side-band-64k ofs-delta shallow no-progress include-tag
multi_ack_detailed no-done symref=HEAD:refs/heads/master
agent=git/2:2.1.1~peff-bare-reflogs-fetch-616-gc016f98
... ref information removed ...
Indicating that GitHub is using a custom git version: git/2:2.1.1~peff-bare-reflogs-fetch-616-gc016f98
.
SSH
SSH remotes invoke the git-upload-pack
process on the remote server to communicate. You can ssh into your remote and execute that process. Like in the HTTPS example, the first line will contain the capabilities. Unlike the HTTPS example, you're expected to perform an interactive negotiation for what you're trying to fetch, so you'll need to instruct the remote that you don't want to communicate.
As part of the git protocol, that means that you'll need to write the length of the command, followed by the command itself (in this case, done
) and a newline. This is 9 bytes (four bytes for the length, four bytes for the command, and a byte for the newline). So the instruction that you'll be giving the remote is 0009done\n
.
echo '0009done' | ssh <host> git-upload-pack <repository> | head -1
For example, to get this information for ssh://[email protected]/libgit2/libgit2
aka [email protected]:libgit2/libgit2
:
echo '0009done' | ssh [email protected] git-upload-pack /libgit2/libgit2 | head -1
014c13502d9e7f6c51a5f93ea39e14db707d382dc996 HEADmulti_ack thin-pack side-band side-band-64k ofs-delta shallow deepen-since deepen-not deepen-relative no-progress include-tag multi_ack_detailed allow-tip-sha1-in-want allow-reachable-sha1-in-want symref=HEAD:refs/heads/main filter object-format=sha1 agent=git/github-g54d96f1f66a0
Indicating that the current version of git
serving my github.com
request is git/github-g54d96f1f66a0
, indicating that it's a development build from commit 54d96f1f66a0
, which suggests that they're testing a change in production.
In similar way to what was suggested by Edward Thomson, you can also use environment debugging variables:
GIT_TRACE_PACKET=true git ls-remote --heads https://github.com/libgit2/libgit2.git |& grep agent
12:31:40.317199 pkt-line.c:80 packet: git< f92d495d44bff2bdb6fd99524a93986ea268c9e8 HEAD\0multi_ack thin-pack side-band side-band-64k ofs-delta shallow deepen-since deepen-not deepen-relative no-progress include-tag multi_ack_detailed no-done symref=HEAD:refs/heads/master agent=git/github-g956b612bf136
And again, it looks like GitHub is using custom build of Git: agent=git/github-g956b612bf136
.