rugged 1.5.0.1 → 1.7.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (250) hide show
  1. checksums.yaml +4 -4
  2. data/ext/rugged/extconf.rb +2 -2
  3. data/ext/rugged/rugged_allocator.c +0 -54
  4. data/ext/rugged/rugged_blame.c +2 -0
  5. data/ext/rugged/rugged_blob.c +3 -0
  6. data/ext/rugged/rugged_commit.c +1 -0
  7. data/ext/rugged/rugged_config.c +2 -0
  8. data/ext/rugged/rugged_diff.c +1 -0
  9. data/ext/rugged/rugged_index.c +2 -0
  10. data/ext/rugged/rugged_patch.c +1 -0
  11. data/ext/rugged/rugged_rebase.c +1 -0
  12. data/ext/rugged/rugged_reference.c +1 -0
  13. data/ext/rugged/rugged_remote.c +1 -0
  14. data/ext/rugged/rugged_repo.c +5 -2
  15. data/ext/rugged/rugged_revwalk.c +5 -1
  16. data/ext/rugged/rugged_submodule.c +1 -0
  17. data/ext/rugged/rugged_tag.c +1 -0
  18. data/ext/rugged/rugged_tree.c +4 -0
  19. data/lib/rugged/index.rb +1 -1
  20. data/lib/rugged/tree.rb +1 -1
  21. data/lib/rugged/version.rb +1 -1
  22. data/vendor/libgit2/CMakeLists.txt +7 -8
  23. data/vendor/libgit2/COPYING +30 -0
  24. data/vendor/libgit2/cmake/CheckPrototypeDefinitionSafe.cmake +16 -0
  25. data/vendor/libgit2/cmake/ExperimentalFeatures.cmake +23 -0
  26. data/vendor/libgit2/cmake/SelectGSSAPI.cmake +3 -3
  27. data/vendor/libgit2/cmake/SelectHTTPSBackend.cmake +21 -2
  28. data/vendor/libgit2/cmake/SelectHashes.cmake +4 -0
  29. data/vendor/libgit2/cmake/SelectXdiff.cmake +9 -0
  30. data/vendor/libgit2/deps/ntlmclient/CMakeLists.txt +2 -0
  31. data/vendor/libgit2/deps/pcre/LICENCE +5 -5
  32. data/vendor/libgit2/deps/pcre/pcre.h +2 -2
  33. data/vendor/libgit2/deps/pcre/pcre_compile.c +6 -3
  34. data/vendor/libgit2/deps/pcre/pcre_exec.c +2 -2
  35. data/vendor/libgit2/deps/xdiff/CMakeLists.txt +28 -0
  36. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/git-xdiff.h +4 -1
  37. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xdiffi.c +19 -18
  38. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xdiffi.h +2 -4
  39. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xemit.c +3 -3
  40. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xhistogram.c +7 -18
  41. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xmacros.h +18 -1
  42. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xmerge.c +24 -22
  43. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xpatience.c +21 -30
  44. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xprepare.c +13 -30
  45. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xutils.c +18 -1
  46. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xutils.h +2 -1
  47. data/vendor/libgit2/include/git2/common.h +38 -6
  48. data/vendor/libgit2/include/git2/deprecated.h +6 -0
  49. data/vendor/libgit2/include/git2/diff.h +42 -4
  50. data/vendor/libgit2/include/git2/errors.h +4 -2
  51. data/vendor/libgit2/include/git2/experimental.h +20 -0
  52. data/vendor/libgit2/include/git2/index.h +9 -0
  53. data/vendor/libgit2/include/git2/indexer.h +29 -0
  54. data/vendor/libgit2/include/git2/object.h +28 -2
  55. data/vendor/libgit2/include/git2/odb.h +58 -7
  56. data/vendor/libgit2/include/git2/odb_backend.h +106 -18
  57. data/vendor/libgit2/include/git2/oid.h +116 -16
  58. data/vendor/libgit2/include/git2/remote.h +18 -0
  59. data/vendor/libgit2/include/git2/repository.h +32 -3
  60. data/vendor/libgit2/include/git2/stash.h +60 -6
  61. data/vendor/libgit2/include/git2/strarray.h +0 -13
  62. data/vendor/libgit2/include/git2/sys/alloc.h +0 -34
  63. data/vendor/libgit2/include/git2/sys/commit_graph.h +12 -2
  64. data/vendor/libgit2/include/git2/sys/midx.h +5 -1
  65. data/vendor/libgit2/include/git2/sys/odb_backend.h +1 -1
  66. data/vendor/libgit2/include/git2/sys/stream.h +16 -2
  67. data/vendor/libgit2/include/git2/sys/transport.h +32 -2
  68. data/vendor/libgit2/include/git2/version.h +4 -4
  69. data/vendor/libgit2/include/git2/worktree.h +3 -1
  70. data/vendor/libgit2/include/git2.h +1 -0
  71. data/vendor/libgit2/src/CMakeLists.txt +34 -17
  72. data/vendor/libgit2/src/cli/CMakeLists.txt +5 -2
  73. data/vendor/libgit2/src/cli/cmd_clone.c +22 -6
  74. data/vendor/libgit2/src/cli/cmd_hash_object.c +27 -8
  75. data/vendor/libgit2/src/cli/opt.c +1 -1
  76. data/vendor/libgit2/src/cli/progress.c +9 -8
  77. data/vendor/libgit2/src/cli/progress.h +4 -4
  78. data/vendor/libgit2/src/libgit2/CMakeLists.txt +25 -34
  79. data/vendor/libgit2/src/libgit2/annotated_commit.c +2 -2
  80. data/vendor/libgit2/src/libgit2/annotated_commit.h +1 -1
  81. data/vendor/libgit2/src/libgit2/apply.c +4 -3
  82. data/vendor/libgit2/src/libgit2/attr_file.c +1 -1
  83. data/vendor/libgit2/src/libgit2/attrcache.c +1 -1
  84. data/vendor/libgit2/src/libgit2/blame.c +23 -14
  85. data/vendor/libgit2/src/libgit2/blame_git.c +0 -1
  86. data/vendor/libgit2/src/libgit2/blob.c +4 -2
  87. data/vendor/libgit2/src/libgit2/blob.h +2 -2
  88. data/vendor/libgit2/src/libgit2/branch.c +2 -2
  89. data/vendor/libgit2/src/libgit2/cherrypick.c +3 -3
  90. data/vendor/libgit2/src/libgit2/clone.c +34 -3
  91. data/vendor/libgit2/src/libgit2/commit.c +78 -21
  92. data/vendor/libgit2/src/libgit2/commit.h +25 -7
  93. data/vendor/libgit2/src/libgit2/commit_graph.c +129 -47
  94. data/vendor/libgit2/src/libgit2/commit_graph.h +23 -4
  95. data/vendor/libgit2/src/libgit2/commit_list.c +16 -5
  96. data/vendor/libgit2/src/libgit2/commit_list.h +1 -0
  97. data/vendor/libgit2/src/libgit2/config.c +6 -3
  98. data/vendor/libgit2/src/libgit2/config_file.c +16 -10
  99. data/vendor/libgit2/src/libgit2/describe.c +11 -8
  100. data/vendor/libgit2/src/libgit2/diff.c +19 -6
  101. data/vendor/libgit2/src/libgit2/diff.h +6 -6
  102. data/vendor/libgit2/src/libgit2/diff_file.c +16 -7
  103. data/vendor/libgit2/src/libgit2/diff_generate.c +37 -11
  104. data/vendor/libgit2/src/libgit2/diff_parse.c +20 -4
  105. data/vendor/libgit2/src/libgit2/diff_print.c +26 -7
  106. data/vendor/libgit2/src/libgit2/diff_tform.c +4 -0
  107. data/vendor/libgit2/src/libgit2/diff_xdiff.h +1 -1
  108. data/vendor/libgit2/src/libgit2/email.c +4 -3
  109. data/vendor/libgit2/src/libgit2/errors.c +73 -18
  110. data/vendor/libgit2/src/libgit2/experimental.h.in +13 -0
  111. data/vendor/libgit2/src/libgit2/fetch.c +38 -13
  112. data/vendor/libgit2/src/libgit2/fetch.h +0 -2
  113. data/vendor/libgit2/src/libgit2/fetchhead.c +11 -9
  114. data/vendor/libgit2/src/libgit2/grafts.c +272 -0
  115. data/vendor/libgit2/src/libgit2/grafts.h +36 -0
  116. data/vendor/libgit2/src/libgit2/ident.c +3 -3
  117. data/vendor/libgit2/src/libgit2/index.c +327 -123
  118. data/vendor/libgit2/src/libgit2/index.h +14 -1
  119. data/vendor/libgit2/src/libgit2/indexer.c +116 -46
  120. data/vendor/libgit2/src/libgit2/iterator.c +21 -4
  121. data/vendor/libgit2/src/libgit2/iterator.h +3 -0
  122. data/vendor/libgit2/src/libgit2/libgit2.c +58 -0
  123. data/vendor/libgit2/src/libgit2/merge.c +14 -9
  124. data/vendor/libgit2/src/libgit2/merge_file.c +0 -2
  125. data/vendor/libgit2/src/libgit2/midx.c +68 -38
  126. data/vendor/libgit2/src/libgit2/midx.h +13 -3
  127. data/vendor/libgit2/src/libgit2/mwindow.c +5 -2
  128. data/vendor/libgit2/src/libgit2/mwindow.h +4 -1
  129. data/vendor/libgit2/src/libgit2/notes.c +9 -8
  130. data/vendor/libgit2/src/libgit2/object.c +118 -29
  131. data/vendor/libgit2/src/libgit2/object.h +17 -2
  132. data/vendor/libgit2/src/libgit2/odb.c +224 -55
  133. data/vendor/libgit2/src/libgit2/odb.h +43 -4
  134. data/vendor/libgit2/src/libgit2/odb_loose.c +128 -70
  135. data/vendor/libgit2/src/libgit2/odb_pack.c +111 -46
  136. data/vendor/libgit2/src/libgit2/oid.c +141 -77
  137. data/vendor/libgit2/src/libgit2/oid.h +183 -9
  138. data/vendor/libgit2/src/libgit2/oidarray.c +49 -3
  139. data/vendor/libgit2/src/libgit2/oidarray.h +5 -1
  140. data/vendor/libgit2/src/libgit2/pack-objects.c +31 -13
  141. data/vendor/libgit2/src/libgit2/pack-objects.h +5 -2
  142. data/vendor/libgit2/src/libgit2/pack.c +93 -70
  143. data/vendor/libgit2/src/libgit2/pack.h +29 -15
  144. data/vendor/libgit2/src/libgit2/parse.c +8 -4
  145. data/vendor/libgit2/src/libgit2/parse.h +1 -1
  146. data/vendor/libgit2/src/libgit2/patch.h +7 -1
  147. data/vendor/libgit2/src/libgit2/patch_generate.c +24 -5
  148. data/vendor/libgit2/src/libgit2/patch_parse.c +16 -8
  149. data/vendor/libgit2/src/libgit2/push.c +13 -3
  150. data/vendor/libgit2/src/libgit2/reader.c +1 -1
  151. data/vendor/libgit2/src/libgit2/rebase.c +72 -83
  152. data/vendor/libgit2/src/libgit2/refdb_fs.c +92 -52
  153. data/vendor/libgit2/src/libgit2/reflog.c +7 -5
  154. data/vendor/libgit2/src/libgit2/reflog.h +1 -2
  155. data/vendor/libgit2/src/libgit2/refs.c +9 -0
  156. data/vendor/libgit2/src/libgit2/remote.c +47 -37
  157. data/vendor/libgit2/src/libgit2/remote.h +41 -0
  158. data/vendor/libgit2/src/libgit2/repository.c +784 -329
  159. data/vendor/libgit2/src/libgit2/repository.h +26 -2
  160. data/vendor/libgit2/src/libgit2/reset.c +2 -2
  161. data/vendor/libgit2/src/libgit2/revert.c +8 -11
  162. data/vendor/libgit2/src/libgit2/revparse.c +23 -7
  163. data/vendor/libgit2/src/libgit2/revwalk.c +31 -5
  164. data/vendor/libgit2/src/libgit2/stash.c +209 -33
  165. data/vendor/libgit2/src/libgit2/strarray.c +1 -0
  166. data/vendor/libgit2/src/libgit2/strarray.h +25 -0
  167. data/vendor/libgit2/src/libgit2/streams/mbedtls.c +0 -1
  168. data/vendor/libgit2/src/libgit2/streams/openssl.c +9 -17
  169. data/vendor/libgit2/src/libgit2/streams/openssl_dynamic.c +7 -3
  170. data/vendor/libgit2/src/libgit2/streams/schannel.c +715 -0
  171. data/vendor/libgit2/src/libgit2/streams/schannel.h +28 -0
  172. data/vendor/libgit2/src/libgit2/streams/socket.c +240 -51
  173. data/vendor/libgit2/src/libgit2/streams/socket.h +3 -1
  174. data/vendor/libgit2/src/libgit2/streams/stransport.c +40 -12
  175. data/vendor/libgit2/src/libgit2/streams/tls.c +5 -0
  176. data/vendor/libgit2/src/libgit2/submodule.c +6 -2
  177. data/vendor/libgit2/src/libgit2/submodule.h +3 -3
  178. data/vendor/libgit2/src/libgit2/sysdir.c +294 -7
  179. data/vendor/libgit2/src/libgit2/sysdir.h +41 -9
  180. data/vendor/libgit2/src/libgit2/tag.c +29 -10
  181. data/vendor/libgit2/src/libgit2/tag.h +2 -2
  182. data/vendor/libgit2/src/libgit2/threadstate.c +15 -2
  183. data/vendor/libgit2/src/libgit2/threadstate.h +1 -3
  184. data/vendor/libgit2/src/libgit2/transports/auth.h +1 -2
  185. data/vendor/libgit2/src/libgit2/transports/{auth_negotiate.c → auth_gssapi.c} +32 -32
  186. data/vendor/libgit2/src/libgit2/transports/auth_negotiate.h +1 -1
  187. data/vendor/libgit2/src/libgit2/transports/auth_ntlm.h +1 -1
  188. data/vendor/libgit2/src/libgit2/transports/{auth_ntlm.c → auth_ntlmclient.c} +12 -12
  189. data/vendor/libgit2/src/libgit2/transports/auth_sspi.c +341 -0
  190. data/vendor/libgit2/src/libgit2/transports/git.c +7 -8
  191. data/vendor/libgit2/src/libgit2/transports/http.c +15 -9
  192. data/vendor/libgit2/src/libgit2/transports/httpclient.c +14 -0
  193. data/vendor/libgit2/src/libgit2/transports/httpclient.h +10 -0
  194. data/vendor/libgit2/src/libgit2/transports/local.c +27 -4
  195. data/vendor/libgit2/src/libgit2/transports/smart.c +68 -27
  196. data/vendor/libgit2/src/libgit2/transports/smart.h +33 -9
  197. data/vendor/libgit2/src/libgit2/transports/smart_pkt.c +281 -49
  198. data/vendor/libgit2/src/libgit2/transports/smart_protocol.c +192 -55
  199. data/vendor/libgit2/src/libgit2/transports/ssh.c +334 -102
  200. data/vendor/libgit2/src/libgit2/transports/winhttp.c +22 -18
  201. data/vendor/libgit2/src/libgit2/tree-cache.c +26 -16
  202. data/vendor/libgit2/src/libgit2/tree-cache.h +5 -3
  203. data/vendor/libgit2/src/libgit2/tree.c +23 -17
  204. data/vendor/libgit2/src/libgit2/tree.h +2 -2
  205. data/vendor/libgit2/src/libgit2/worktree.c +30 -10
  206. data/vendor/libgit2/src/util/CMakeLists.txt +6 -1
  207. data/vendor/libgit2/src/util/alloc.c +65 -6
  208. data/vendor/libgit2/src/util/alloc.h +34 -9
  209. data/vendor/libgit2/src/util/allocators/failalloc.c +0 -60
  210. data/vendor/libgit2/src/util/allocators/failalloc.h +0 -6
  211. data/vendor/libgit2/src/util/allocators/stdalloc.c +2 -105
  212. data/vendor/libgit2/src/util/allocators/win32_leakcheck.c +0 -68
  213. data/vendor/libgit2/src/util/array.h +6 -1
  214. data/vendor/libgit2/src/util/cc-compat.h +2 -0
  215. data/vendor/libgit2/src/util/filebuf.c +6 -1
  216. data/vendor/libgit2/src/util/filebuf.h +19 -6
  217. data/vendor/libgit2/src/util/fs_path.c +2 -2
  218. data/vendor/libgit2/src/util/futils.c +8 -8
  219. data/vendor/libgit2/src/{features.h.in → util/git2_features.h.in} +9 -3
  220. data/vendor/libgit2/src/util/git2_util.h +2 -2
  221. data/vendor/libgit2/src/util/hash/openssl.c +4 -3
  222. data/vendor/libgit2/src/util/hash/rfc6234/sha.h +0 -112
  223. data/vendor/libgit2/src/util/hash.h +13 -0
  224. data/vendor/libgit2/src/util/net.c +492 -87
  225. data/vendor/libgit2/src/util/net.h +32 -0
  226. data/vendor/libgit2/src/util/posix.c +54 -0
  227. data/vendor/libgit2/src/util/posix.h +24 -0
  228. data/vendor/libgit2/src/util/rand.c +10 -4
  229. data/vendor/libgit2/src/util/regexp.c +3 -3
  230. data/vendor/libgit2/src/util/staticstr.h +66 -0
  231. data/vendor/libgit2/src/util/thread.h +20 -19
  232. data/vendor/libgit2/src/util/util.c +15 -10
  233. data/vendor/libgit2/src/util/util.h +25 -16
  234. data/vendor/libgit2/src/util/win32/error.c +1 -1
  235. data/vendor/libgit2/src/util/win32/path_w32.c +8 -8
  236. data/vendor/libgit2/src/util/win32/posix_w32.c +1 -1
  237. data/vendor/libgit2/src/util/win32/utf-conv.c +73 -75
  238. data/vendor/libgit2/src/util/win32/utf-conv.h +81 -14
  239. data/vendor/libgit2/src/util/win32/w32_util.c +1 -1
  240. metadata +34 -26
  241. data/vendor/libgit2/cmake/SelectWinHTTP.cmake +0 -17
  242. data/vendor/libgit2/src/libgit2/netops.c +0 -124
  243. data/vendor/libgit2/src/libgit2/netops.h +0 -68
  244. data/vendor/libgit2/src/util/win32/findfile.c +0 -286
  245. data/vendor/libgit2/src/util/win32/findfile.h +0 -22
  246. /data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xdiff.h +0 -0
  247. /data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xemit.h +0 -0
  248. /data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xinclude.h +0 -0
  249. /data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xprepare.h +0 -0
  250. /data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xtypes.h +0 -0
@@ -9,9 +9,9 @@
9
9
 
10
10
  #include "smart.h"
11
11
  #include "util.h"
12
- #include "netops.h"
13
12
  #include "posix.h"
14
13
  #include "str.h"
14
+ #include "oid.h"
15
15
 
16
16
  #include "git2/types.h"
17
17
  #include "git2/errors.h"
@@ -20,11 +20,14 @@
20
20
 
21
21
  #include <ctype.h>
22
22
 
23
- #define PKT_LEN_SIZE 4
24
- static const char pkt_done_str[] = "0009done\n";
25
- static const char pkt_flush_str[] = "0000";
26
- static const char pkt_have_prefix[] = "0032have ";
27
- static const char pkt_want_prefix[] = "0032want ";
23
+ #define PKT_DONE_STR "0009done\n"
24
+ #define PKT_FLUSH_STR "0000"
25
+ #define PKT_HAVE_PREFIX "have "
26
+ #define PKT_WANT_PREFIX "want "
27
+
28
+ #define PKT_LEN_SIZE 4
29
+ #define PKT_MAX_SIZE 0xffff
30
+ #define PKT_MAX_WANTLEN (PKT_LEN_SIZE + CONST_STRLEN(PKT_WANT_PREFIX) + GIT_OID_MAX_HEXSIZE + 1)
28
31
 
29
32
  static int flush_pkt(git_pkt **out)
30
33
  {
@@ -40,9 +43,16 @@ static int flush_pkt(git_pkt **out)
40
43
  }
41
44
 
42
45
  /* the rest of the line will be useful for multi_ack and multi_ack_detailed */
43
- static int ack_pkt(git_pkt **out, const char *line, size_t len)
46
+ static int ack_pkt(
47
+ git_pkt **out,
48
+ const char *line,
49
+ size_t len,
50
+ git_pkt_parse_data *data)
44
51
  {
45
52
  git_pkt_ack *pkt;
53
+ size_t oid_hexsize = git_oid_hexsize(data->oid_type);
54
+
55
+ GIT_ASSERT(data && data->oid_type);
46
56
 
47
57
  pkt = git__calloc(1, sizeof(git_pkt_ack));
48
58
  GIT_ERROR_CHECK_ALLOC(pkt);
@@ -53,10 +63,11 @@ static int ack_pkt(git_pkt **out, const char *line, size_t len)
53
63
  line += 4;
54
64
  len -= 4;
55
65
 
56
- if (len < GIT_OID_HEXSZ || git_oid_fromstr(&pkt->oid, line) < 0)
66
+ if (len < oid_hexsize ||
67
+ git_oid__fromstr(&pkt->oid, line, data->oid_type) < 0)
57
68
  goto out_err;
58
- line += GIT_OID_HEXSZ;
59
- len -= GIT_OID_HEXSZ;
69
+ line += oid_hexsize;
70
+ len -= oid_hexsize;
60
71
 
61
72
  if (len && line[0] == ' ') {
62
73
  line++;
@@ -210,25 +221,87 @@ static int sideband_error_pkt(git_pkt **out, const char *line, size_t len)
210
221
  return 0;
211
222
  }
212
223
 
224
+ static int set_data(
225
+ git_pkt_parse_data *data,
226
+ const char *line,
227
+ size_t len)
228
+ {
229
+ const char *caps, *format_str = NULL, *eos;
230
+ size_t format_len;
231
+ git_oid_t remote_oid_type;
232
+
233
+ GIT_ASSERT_ARG(data);
234
+
235
+ if ((caps = memchr(line, '\0', len)) != NULL) {
236
+ caps++;
237
+
238
+ if (strncmp(caps, "object-format=", CONST_STRLEN("object-format=")) == 0)
239
+ format_str = caps + CONST_STRLEN("object-format=");
240
+ else if ((format_str = strstr(caps, " object-format=")) != NULL)
241
+ format_str += CONST_STRLEN(" object-format=");
242
+ }
243
+
244
+ if (format_str) {
245
+ if ((eos = strchr(format_str, ' ')) == NULL)
246
+ eos = strchr(format_str, '\0');
247
+
248
+ GIT_ASSERT(eos);
249
+
250
+ format_len = eos - format_str;
251
+
252
+ if ((remote_oid_type = git_oid_type_fromstrn(format_str, format_len)) == 0) {
253
+ git_error_set(GIT_ERROR_INVALID, "unknown remote object format '%.*s'", (int)format_len, format_str);
254
+ return -1;
255
+ }
256
+ } else {
257
+ remote_oid_type = GIT_OID_SHA1;
258
+ }
259
+
260
+ if (!data->oid_type) {
261
+ data->oid_type = remote_oid_type;
262
+ } else if (data->oid_type != remote_oid_type) {
263
+ git_error_set(GIT_ERROR_INVALID,
264
+ "the local object format '%s' does not match the remote object format '%s'",
265
+ git_oid_type_name(data->oid_type),
266
+ git_oid_type_name(remote_oid_type));
267
+ return -1;
268
+ }
269
+
270
+ return 0;
271
+ }
272
+
213
273
  /*
214
274
  * Parse an other-ref line.
215
275
  */
216
- static int ref_pkt(git_pkt **out, const char *line, size_t len)
276
+ static int ref_pkt(
277
+ git_pkt **out,
278
+ const char *line,
279
+ size_t len,
280
+ git_pkt_parse_data *data)
217
281
  {
218
282
  git_pkt_ref *pkt;
219
- size_t alloclen;
283
+ size_t alloclen, oid_hexsize;
220
284
 
221
285
  pkt = git__calloc(1, sizeof(git_pkt_ref));
222
286
  GIT_ERROR_CHECK_ALLOC(pkt);
223
287
  pkt->type = GIT_PKT_REF;
224
288
 
225
- if (len < GIT_OID_HEXSZ || git_oid_fromstr(&pkt->head.oid, line) < 0)
289
+ /* Determine OID type from capabilities */
290
+ if (!data->seen_capabilities && set_data(data, line, len) < 0)
291
+ return -1;
292
+
293
+ GIT_ASSERT(data->oid_type);
294
+ oid_hexsize = git_oid_hexsize(data->oid_type);
295
+
296
+ if (len < oid_hexsize ||
297
+ git_oid__fromstr(&pkt->head.oid, line, data->oid_type) < 0)
226
298
  goto out_err;
227
- line += GIT_OID_HEXSZ;
228
- len -= GIT_OID_HEXSZ;
299
+ line += oid_hexsize;
300
+ len -= oid_hexsize;
229
301
 
230
302
  if (git__prefixncmp(line, len, " "))
231
303
  goto out_err;
304
+
232
305
  line++;
233
306
  len--;
234
307
 
@@ -245,8 +318,14 @@ static int ref_pkt(git_pkt **out, const char *line, size_t len)
245
318
  memcpy(pkt->head.name, line, len);
246
319
  pkt->head.name[len] = '\0';
247
320
 
248
- if (strlen(pkt->head.name) < len)
249
- pkt->capabilities = strchr(pkt->head.name, '\0') + 1;
321
+ if (strlen(pkt->head.name) < len) {
322
+ if (!data->seen_capabilities)
323
+ pkt->capabilities = strchr(pkt->head.name, '\0') + 1;
324
+ else
325
+ goto out_err;
326
+ }
327
+
328
+ data->seen_capabilities = 1;
250
329
 
251
330
  *out = (git_pkt *)pkt;
252
331
  return 0;
@@ -363,6 +442,84 @@ static int unpack_pkt(git_pkt **out, const char *line, size_t len)
363
442
  return 0;
364
443
  }
365
444
 
445
+ static int shallow_pkt(
446
+ git_pkt **out,
447
+ const char *line,
448
+ size_t len,
449
+ git_pkt_parse_data *data)
450
+ {
451
+ git_pkt_shallow *pkt;
452
+ size_t oid_hexsize = git_oid_hexsize(data->oid_type);
453
+
454
+ GIT_ASSERT(data && data->oid_type);
455
+
456
+ pkt = git__calloc(1, sizeof(git_pkt_shallow));
457
+ GIT_ERROR_CHECK_ALLOC(pkt);
458
+
459
+ pkt->type = GIT_PKT_SHALLOW;
460
+
461
+ if (git__prefixncmp(line, len, "shallow "))
462
+ goto out_err;
463
+
464
+ line += 8;
465
+ len -= 8;
466
+
467
+ if (len != oid_hexsize)
468
+ goto out_err;
469
+
470
+ git_oid__fromstr(&pkt->oid, line, data->oid_type);
471
+ line += oid_hexsize + 1;
472
+ len -= oid_hexsize + 1;
473
+
474
+ *out = (git_pkt *)pkt;
475
+
476
+ return 0;
477
+
478
+ out_err:
479
+ git_error_set(GIT_ERROR_NET, "invalid packet line");
480
+ git__free(pkt);
481
+ return -1;
482
+ }
483
+
484
+ static int unshallow_pkt(
485
+ git_pkt **out,
486
+ const char *line,
487
+ size_t len,
488
+ git_pkt_parse_data *data)
489
+ {
490
+ git_pkt_shallow *pkt;
491
+ size_t oid_hexsize = git_oid_hexsize(data->oid_type);
492
+
493
+ GIT_ASSERT(data && data->oid_type);
494
+
495
+ pkt = git__calloc(1, sizeof(git_pkt_shallow));
496
+ GIT_ERROR_CHECK_ALLOC(pkt);
497
+
498
+ pkt->type = GIT_PKT_UNSHALLOW;
499
+
500
+ if (git__prefixncmp(line, len, "unshallow "))
501
+ goto out_err;
502
+
503
+ line += 10;
504
+ len -= 10;
505
+
506
+ if (len != oid_hexsize)
507
+ goto out_err;
508
+
509
+ git_oid__fromstr(&pkt->oid, line, data->oid_type);
510
+ line += oid_hexsize + 1;
511
+ len -= oid_hexsize + 1;
512
+
513
+ *out = (git_pkt *) pkt;
514
+
515
+ return 0;
516
+
517
+ out_err:
518
+ git_error_set(GIT_ERROR_NET, "invalid packet line");
519
+ git__free(pkt);
520
+ return -1;
521
+ }
522
+
366
523
  static int parse_len(size_t *out, const char *line, size_t linelen)
367
524
  {
368
525
  char num[PKT_LEN_SIZE + 1];
@@ -415,7 +572,11 @@ static int parse_len(size_t *out, const char *line, size_t linelen)
415
572
  */
416
573
 
417
574
  int git_pkt_parse_line(
418
- git_pkt **pkt, const char **endptr, const char *line, size_t linelen)
575
+ git_pkt **pkt,
576
+ const char **endptr,
577
+ const char *line,
578
+ size_t linelen,
579
+ git_pkt_parse_data *data)
419
580
  {
420
581
  int error;
421
582
  size_t len;
@@ -476,7 +637,7 @@ int git_pkt_parse_line(
476
637
  else if (*line == GIT_SIDE_BAND_ERROR)
477
638
  error = sideband_error_pkt(pkt, line, len);
478
639
  else if (!git__prefixncmp(line, len, "ACK"))
479
- error = ack_pkt(pkt, line, len);
640
+ error = ack_pkt(pkt, line, len, data);
480
641
  else if (!git__prefixncmp(line, len, "NAK"))
481
642
  error = nak_pkt(pkt);
482
643
  else if (!git__prefixncmp(line, len, "ERR"))
@@ -489,8 +650,12 @@ int git_pkt_parse_line(
489
650
  error = ng_pkt(pkt, line, len);
490
651
  else if (!git__prefixncmp(line, len, "unpack"))
491
652
  error = unpack_pkt(pkt, line, len);
653
+ else if (!git__prefixcmp(line, "shallow"))
654
+ error = shallow_pkt(pkt, line, len, data);
655
+ else if (!git__prefixcmp(line, "unshallow"))
656
+ error = unshallow_pkt(pkt, line, len, data);
492
657
  else
493
- error = ref_pkt(pkt, line, len);
658
+ error = ref_pkt(pkt, line, len, data);
494
659
 
495
660
  *endptr = line + len;
496
661
 
@@ -524,14 +689,21 @@ void git_pkt_free(git_pkt *pkt)
524
689
 
525
690
  int git_pkt_buffer_flush(git_str *buf)
526
691
  {
527
- return git_str_put(buf, pkt_flush_str, strlen(pkt_flush_str));
692
+ return git_str_put(buf, PKT_FLUSH_STR, CONST_STRLEN(PKT_FLUSH_STR));
528
693
  }
529
694
 
530
- static int buffer_want_with_caps(const git_remote_head *head, transport_smart_caps *caps, git_str *buf)
695
+ static int buffer_want_with_caps(
696
+ const git_remote_head *head,
697
+ transport_smart_caps *caps,
698
+ git_oid_t oid_type,
699
+ git_str *buf)
531
700
  {
532
701
  git_str str = GIT_STR_INIT;
533
- char oid[GIT_OID_HEXSZ +1] = {0};
534
- size_t len;
702
+ char oid[GIT_OID_MAX_HEXSIZE];
703
+ size_t oid_hexsize, len;
704
+
705
+ oid_hexsize = git_oid_hexsize(oid_type);
706
+ git_oid_fmt(oid, &head->oid);
535
707
 
536
708
  /* Prefer multi_ack_detailed */
537
709
  if (caps->multi_ack_detailed)
@@ -554,22 +726,26 @@ static int buffer_want_with_caps(const git_remote_head *head, transport_smart_ca
554
726
  if (caps->ofs_delta)
555
727
  git_str_puts(&str, GIT_CAP_OFS_DELTA " ");
556
728
 
729
+ if (caps->shallow)
730
+ git_str_puts(&str, GIT_CAP_SHALLOW " ");
731
+
557
732
  if (git_str_oom(&str))
558
733
  return -1;
559
734
 
560
- len = strlen("XXXXwant ") + GIT_OID_HEXSZ + 1 /* NUL */ +
561
- git_str_len(&str) + 1 /* LF */;
562
-
563
- if (len > 0xffff) {
735
+ if (str.size > (PKT_MAX_SIZE - (PKT_MAX_WANTLEN + 1))) {
564
736
  git_error_set(GIT_ERROR_NET,
565
- "tried to produce packet with invalid length %" PRIuZ, len);
737
+ "tried to produce packet with invalid caps length %" PRIuZ, str.size);
566
738
  return -1;
567
739
  }
568
740
 
741
+ len = PKT_LEN_SIZE + CONST_STRLEN(PKT_WANT_PREFIX) +
742
+ oid_hexsize + 1 /* NUL */ +
743
+ git_str_len(&str) + 1 /* LF */;
744
+
569
745
  git_str_grow_by(buf, len);
570
- git_oid_fmt(oid, &head->oid);
571
746
  git_str_printf(buf,
572
- "%04xwant %s %s\n", (unsigned int)len, oid, git_str_cstr(&str));
747
+ "%04x%s%.*s %s\n", (unsigned int)len, PKT_WANT_PREFIX,
748
+ (int)oid_hexsize, oid, git_str_cstr(&str));
573
749
  git_str_dispose(&str);
574
750
 
575
751
  GIT_ERROR_CHECK_ALLOC_STR(buf);
@@ -583,38 +759,81 @@ static int buffer_want_with_caps(const git_remote_head *head, transport_smart_ca
583
759
  */
584
760
 
585
761
  int git_pkt_buffer_wants(
586
- const git_remote_head * const *refs,
587
- size_t count,
762
+ const git_fetch_negotiation *wants,
588
763
  transport_smart_caps *caps,
589
764
  git_str *buf)
590
765
  {
591
- size_t i = 0;
592
766
  const git_remote_head *head;
767
+ char oid[GIT_OID_MAX_HEXSIZE];
768
+ git_oid_t oid_type;
769
+ size_t oid_hexsize, want_len, i = 0;
770
+
771
+ #ifdef GIT_EXPERIMENTAL_SHA256
772
+ oid_type = wants->refs_len > 0 ? wants->refs[0]->oid.type : GIT_OID_SHA1;
773
+ #else
774
+ oid_type = GIT_OID_SHA1;
775
+ #endif
776
+
777
+ oid_hexsize = git_oid_hexsize(oid_type);
778
+
779
+ want_len = PKT_LEN_SIZE + CONST_STRLEN(PKT_WANT_PREFIX) +
780
+ oid_hexsize + 1 /* LF */;
593
781
 
594
782
  if (caps->common) {
595
- for (; i < count; ++i) {
596
- head = refs[i];
783
+ for (; i < wants->refs_len; ++i) {
784
+ head = wants->refs[i];
597
785
  if (!head->local)
598
786
  break;
599
787
  }
600
788
 
601
- if (buffer_want_with_caps(refs[i], caps, buf) < 0)
789
+ if (buffer_want_with_caps(wants->refs[i], caps, oid_type, buf) < 0)
602
790
  return -1;
603
791
 
604
792
  i++;
605
793
  }
606
794
 
607
- for (; i < count; ++i) {
608
- char oid[GIT_OID_HEXSZ];
795
+ for (; i < wants->refs_len; ++i) {
796
+ head = wants->refs[i];
609
797
 
610
- head = refs[i];
611
798
  if (head->local)
612
799
  continue;
613
800
 
614
801
  git_oid_fmt(oid, &head->oid);
615
- git_str_put(buf, pkt_want_prefix, strlen(pkt_want_prefix));
616
- git_str_put(buf, oid, GIT_OID_HEXSZ);
617
- git_str_putc(buf, '\n');
802
+
803
+ git_str_printf(buf, "%04x%s%.*s\n",
804
+ (unsigned int)want_len, PKT_WANT_PREFIX,
805
+ (int)oid_hexsize, oid);
806
+
807
+ if (git_str_oom(buf))
808
+ return -1;
809
+ }
810
+
811
+ /* Tell the server about our shallow objects */
812
+ for (i = 0; i < wants->shallow_roots_len; i++) {
813
+ char oid[GIT_OID_MAX_HEXSIZE + 1];
814
+ git_str shallow_buf = GIT_STR_INIT;
815
+
816
+ git_oid_tostr(oid, GIT_OID_MAX_HEXSIZE + 1, &wants->shallow_roots[i]);
817
+ git_str_puts(&shallow_buf, "shallow ");
818
+ git_str_puts(&shallow_buf, oid);
819
+ git_str_putc(&shallow_buf, '\n');
820
+
821
+ git_str_printf(buf, "%04x%s", (unsigned int)git_str_len(&shallow_buf) + 4, git_str_cstr(&shallow_buf));
822
+
823
+ git_str_dispose(&shallow_buf);
824
+
825
+ if (git_str_oom(buf))
826
+ return -1;
827
+ }
828
+
829
+ if (wants->depth > 0) {
830
+ git_str deepen_buf = GIT_STR_INIT;
831
+
832
+ git_str_printf(&deepen_buf, "deepen %d\n", wants->depth);
833
+ git_str_printf(buf,"%04x%s", (unsigned int)git_str_len(&deepen_buf) + 4, git_str_cstr(&deepen_buf));
834
+
835
+ git_str_dispose(&deepen_buf);
836
+
618
837
  if (git_str_oom(buf))
619
838
  return -1;
620
839
  }
@@ -624,14 +843,27 @@ int git_pkt_buffer_wants(
624
843
 
625
844
  int git_pkt_buffer_have(git_oid *oid, git_str *buf)
626
845
  {
627
- char oidhex[GIT_OID_HEXSZ + 1];
628
-
629
- memset(oidhex, 0x0, sizeof(oidhex));
630
- git_oid_fmt(oidhex, oid);
631
- return git_str_printf(buf, "%s%s\n", pkt_have_prefix, oidhex);
846
+ char oid_str[GIT_OID_MAX_HEXSIZE];
847
+ git_oid_t oid_type;
848
+ size_t oid_hexsize, have_len;
849
+
850
+ #ifdef GIT_EXPERIMENTAL_SHA256
851
+ oid_type = oid->type;
852
+ #else
853
+ oid_type = GIT_OID_SHA1;
854
+ #endif
855
+
856
+ oid_hexsize = git_oid_hexsize(oid_type);
857
+ have_len = PKT_LEN_SIZE + CONST_STRLEN(PKT_HAVE_PREFIX) +
858
+ oid_hexsize + 1 /* LF */;
859
+
860
+ git_oid_fmt(oid_str, oid);
861
+ return git_str_printf(buf, "%04x%s%.*s\n",
862
+ (unsigned int)have_len, PKT_HAVE_PREFIX,
863
+ (int)oid_hexsize, oid_str);
632
864
  }
633
865
 
634
866
  int git_pkt_buffer_done(git_str *buf)
635
867
  {
636
- return git_str_puts(buf, pkt_done_str);
868
+ return git_str_put(buf, PKT_DONE_STR, CONST_STRLEN(PKT_DONE_STR));
637
869
  }