How can I fetch git objects using the smart protocol (raw) over http? -
i'm trying fetch annotation of tag "v2.4.2" github.com/git/git using git smart protocol on http.
// refs
curl -h "user-agent: git/1.8.1" -v https://github.com/git/git/info/refs?service=git-upload-pack
returns refs:
..... 003e2be062dfcfd1fd4aca132ec02a40b56f63776202 refs/tags/v2.4.1 0041aaa7e0d7f8f003c0c8ab34f959083f6d191d44ca refs/tags/v2.4.1^{} 003e29932f3915935d773dc8d52c292cadd81c81071d refs/tags/v2.4.2 00419eabf5b536662000f79978c4d1b6e4eff5c8d785 refs/tags/v2.4.2^{}
// make upload pack request
printf "0031want 00419eabf5b536662000f79978c4d1b6e4eff5c8d785\n0024have 003e2be062dfcfd1fd4aca132ec02a40b56f63776202\n0000" | curl -h "user-agent: git/1.8.1" -v -d @- https://github.com/git/git/git-upload-pack -h "content-type: application/x-git-upload-pack-request" --trace-ascii /dev/stdout
this returns nothing. i'm wondering what's wrong in request (i.e did miscalculate hex?)
warning: --trace-ascii overrides earlier trace/verbose option == info: hostname not found in dns cache == info: trying 192.30.252.130... == info: connected github.com (192.30.252.130) port 443 (#0) == info: tls 1.2 connection using tls_ecdhe_rsa_with_aes_128_cbc_sha256 == info: server certificate: github.com == info: server certificate: digicert sha2 extended validation server ca == info: server certificate: digicert high assurance ev root ca => send header, 170 bytes (0xaa) 0000: post /git/git/git-upload-pack http/1.1 0028: host: github.com 003a: accept: */* 0047: user-agent: git/1.8.1 005e: content-type: application/x-git-upload-pack-request 0093: content-length: 110 00a8: => send data, 110 bytes (0x6e) 0000: 0031want 00419eabf5b536662000f79978c4d1b6e4eff5c8d7850024have 00 0040: 3e2be062dfcfd1fd4aca132ec02a40b56f637762020000 == info: upload sent off: 110 out of 110 bytes <= recv header, 17 bytes (0x11) 0000: http/1.1 200 ok == info: server github babel 2.0 not blacklisted <= recv header, 26 bytes (0x1a) 0000: server: github babel 2.0 <= recv header, 52 bytes (0x34) 0000: content-type: application/x-git-upload-pack-result <= recv header, 28 bytes (0x1c) 0000: transfer-encoding: chunked <= recv header, 40 bytes (0x28) 0000: expires: fri, 01 jan 1980 00:00:00 gmt <= recv header, 18 bytes (0x12) 0000: pragma: no-cache <= recv header, 53 bytes (0x35) 0000: cache-control: no-cache, max-age=0, must-revalidate <= recv header, 23 bytes (0x17) 0000: vary: accept-encoding <= recv header, 2 bytes (0x2) 0000: <= recv data, 5 bytes (0x5) 0000: 0 0003: == info: connection #0 host github.com left intact
why trying this?
- i don't have write access file system
- avoid fetching unnecessary data (i.e commits)
- standard api/protocol
commit hex
you didn't miscalculate hex, you're not passing correct value. remember each line in smart protocol preceded length count:
<length><data>
so line looks this:
00419eabf5b536662000f79978c4d1b6e4eff5c8d785 refs/tags/v2.4.2^{}
you need discard first 4 characters, makes actual commit hex:
9eabf5b536662000f79978c4d1b6e4eff5c8d785
request format
when post
ing request, have
, want
lines supposed separated newline, if take @ output curl
, can see there no newline:
=> send data, 110 bytes (0x6e) 0000: 0031want 00419eabf5b536662000f79978c4d1b6e4eff5c8d7850024have 00 0040: 3e2be062dfcfd1fd4aca132ec02a40b56f637762020000
you need use --data-binary
instead of --data
:
--data-binary @-
you need prefix these lines length count, , need end line consisting of 0000
:
0032want 9eabf5b536662000f79978c4d1b6e4eff5c8d785 0032have 2be062dfcfd1fd4aca132ec02a40b56f63776202 0000
debugging tips
you can set git_trace_packet=1
in environment if want copious debugging information git
see it's sending , forth.
and that's wrote
i'm not able response myself, given above information, figured help.
update
so, fun.
i set git server locally (using git http-backend
, thttpd), , ran tcpdump
grab traffic generated git remote update
operation. turns out need separate want
, have
directives null command, 0000
(no newline, because length encodes newlines, too). is:
<length>want <commitid><newline> 0000<length>have <commitid><newline> <length>done
e.g:
0032want 9eabf5b536662000f79978c4d1b6e4eff5c8d785 00000032have 2be062dfcfd1fd4aca132ec02a40b56f63776202 0009done
that gives me:
0000: post /git/git/git-upload-pack http/1.1 0028: host: github.com 003a: accept: */* 0047: content-type: application/x-git-upload-pack-request 007c: user-agent: git/1.8 0091: content-length: 113 00a6: => send data, 113 bytes (0x71) 0000: 0032want 9eabf5b536662000f79978c4d1b6e4eff5c8d785.00000032have 2 0040: be062dfcfd1fd4aca132ec02a40b56f63776202.0009done. == info: upload sent off: 113 out of 113 bytes <= recv header, 17 bytes (0x11) 0000: http/1.1 200 ok <= recv header, 26 bytes (0x1a) 0000: server: github babel 2.0 <= recv header, 52 bytes (0x34) 0000: content-type: application/x-git-upload-pack-result <= recv header, 28 bytes (0x1c) 0000: transfer-encoding: chunked <= recv header, 40 bytes (0x28) 0000: expires: fri, 01 jan 1980 00:00:00 gmt <= recv header, 18 bytes (0x12) 0000: pragma: no-cache <= recv header, 53 bytes (0x35) 0000: cache-control: no-cache, max-age=0, must-revalidate <= recv header, 23 bytes (0x17) 0000: vary: accept-encoding <= recv header, 2 bytes (0x2) 0000: <= recv data, 4 bytes (0x4) 0000: 31 <= recv data, 51 bytes (0x33) 0000: 0031ack 2be062dfcfd1fd4aca132ec02a40b56f63776202. <= recv data, 6 bytes (0x6) 0000: 1fff <= recv data, 1370 bytes (0x55a) 0000: pack.......[..x...an.0...z.?`..d.*..@..z..(.tu......>~b.....]..8 0040: 2...j).oq}..#.....'......[..8k..t..,%.s..u..@l..xt...o......'... [....]
double-bonus update
you can use git unpack-objects
command extract packfile. can see above trace, first length-encoded response ( 0031ack 2be062dfcfd1fd4aca132ec02a40b56f63776202
) followed pack data, need discard first line:
$ git init tmprepo $ cd temprepo $ tail -n +2 output_from_curl | git unpack-objects unpacking objects: 100% (91/91), done. $ find .git/objects -type f | head -3 $ git cat-file -p dc940e63c453199dd9a7285533fbf2355bab03d1 /* * git - information manager hell * * copyright (c) linus torvalds, 2005 * * handles basic git sha1 object files - packing, unpacking, * creation etc. */ [...]
Comments
Post a Comment