rugged 1.5.1 → 1.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (154) hide show
  1. checksums.yaml +4 -4
  2. data/ext/rugged/extconf.rb +2 -2
  3. data/ext/rugged/rugged_blame.c +2 -0
  4. data/ext/rugged/rugged_blob.c +3 -0
  5. data/ext/rugged/rugged_commit.c +1 -0
  6. data/ext/rugged/rugged_config.c +2 -0
  7. data/ext/rugged/rugged_diff.c +1 -0
  8. data/ext/rugged/rugged_index.c +2 -0
  9. data/ext/rugged/rugged_patch.c +1 -0
  10. data/ext/rugged/rugged_rebase.c +1 -0
  11. data/ext/rugged/rugged_reference.c +1 -0
  12. data/ext/rugged/rugged_remote.c +1 -0
  13. data/ext/rugged/rugged_repo.c +5 -2
  14. data/ext/rugged/rugged_revwalk.c +5 -1
  15. data/ext/rugged/rugged_submodule.c +1 -0
  16. data/ext/rugged/rugged_tag.c +1 -0
  17. data/ext/rugged/rugged_tree.c +4 -0
  18. data/lib/rugged/index.rb +1 -1
  19. data/lib/rugged/tree.rb +1 -1
  20. data/lib/rugged/version.rb +1 -1
  21. data/vendor/libgit2/CMakeLists.txt +5 -1
  22. data/vendor/libgit2/COPYING +30 -0
  23. data/vendor/libgit2/cmake/ExperimentalFeatures.cmake +23 -0
  24. data/vendor/libgit2/deps/ntlmclient/CMakeLists.txt +2 -0
  25. data/vendor/libgit2/include/git2/common.h +13 -6
  26. data/vendor/libgit2/include/git2/deprecated.h +6 -0
  27. data/vendor/libgit2/include/git2/diff.h +1 -1
  28. data/vendor/libgit2/include/git2/experimental.h +20 -0
  29. data/vendor/libgit2/include/git2/indexer.h +29 -0
  30. data/vendor/libgit2/include/git2/object.h +28 -2
  31. data/vendor/libgit2/include/git2/odb.h +58 -7
  32. data/vendor/libgit2/include/git2/odb_backend.h +106 -18
  33. data/vendor/libgit2/include/git2/oid.h +115 -15
  34. data/vendor/libgit2/include/git2/repository.h +20 -1
  35. data/vendor/libgit2/include/git2/stash.h +60 -6
  36. data/vendor/libgit2/include/git2/strarray.h +0 -13
  37. data/vendor/libgit2/include/git2/sys/odb_backend.h +1 -1
  38. data/vendor/libgit2/include/git2/sys/transport.h +12 -0
  39. data/vendor/libgit2/include/git2/version.h +4 -4
  40. data/vendor/libgit2/include/git2.h +1 -0
  41. data/vendor/libgit2/src/CMakeLists.txt +0 -6
  42. data/vendor/libgit2/src/cli/CMakeLists.txt +6 -2
  43. data/vendor/libgit2/src/cli/cmd_hash_object.c +27 -8
  44. data/vendor/libgit2/src/cli/opt.c +1 -1
  45. data/vendor/libgit2/src/libgit2/CMakeLists.txt +25 -15
  46. data/vendor/libgit2/src/libgit2/annotated_commit.c +1 -1
  47. data/vendor/libgit2/src/libgit2/annotated_commit.h +1 -1
  48. data/vendor/libgit2/src/libgit2/attr_file.c +1 -1
  49. data/vendor/libgit2/src/libgit2/attrcache.c +1 -1
  50. data/vendor/libgit2/src/libgit2/blame.c +2 -0
  51. data/vendor/libgit2/src/libgit2/blob.c +4 -2
  52. data/vendor/libgit2/src/libgit2/blob.h +2 -2
  53. data/vendor/libgit2/src/libgit2/branch.c +2 -2
  54. data/vendor/libgit2/src/libgit2/cherrypick.c +3 -3
  55. data/vendor/libgit2/src/libgit2/clone.c +31 -2
  56. data/vendor/libgit2/src/libgit2/commit.c +52 -17
  57. data/vendor/libgit2/src/libgit2/commit.h +25 -7
  58. data/vendor/libgit2/src/libgit2/commit_graph.c +47 -32
  59. data/vendor/libgit2/src/libgit2/commit_graph.h +3 -0
  60. data/vendor/libgit2/src/libgit2/commit_list.c +6 -2
  61. data/vendor/libgit2/src/libgit2/config.c +1 -1
  62. data/vendor/libgit2/src/libgit2/config_file.c +2 -2
  63. data/vendor/libgit2/src/libgit2/describe.c +8 -8
  64. data/vendor/libgit2/src/libgit2/diff.c +5 -1
  65. data/vendor/libgit2/src/libgit2/diff_file.c +15 -6
  66. data/vendor/libgit2/src/libgit2/diff_generate.c +17 -12
  67. data/vendor/libgit2/src/libgit2/diff_print.c +5 -5
  68. data/vendor/libgit2/src/libgit2/diff_tform.c +4 -0
  69. data/vendor/libgit2/src/libgit2/email.c +2 -2
  70. data/vendor/libgit2/src/libgit2/experimental.h.in +13 -0
  71. data/vendor/libgit2/src/libgit2/fetch.c +3 -6
  72. data/vendor/libgit2/src/libgit2/fetchhead.c +4 -4
  73. data/vendor/libgit2/src/libgit2/ident.c +3 -3
  74. data/vendor/libgit2/src/libgit2/index.c +11 -9
  75. data/vendor/libgit2/src/libgit2/indexer.c +107 -44
  76. data/vendor/libgit2/src/libgit2/iterator.c +4 -2
  77. data/vendor/libgit2/src/libgit2/libgit2.c +19 -0
  78. data/vendor/libgit2/src/libgit2/merge.c +3 -3
  79. data/vendor/libgit2/src/libgit2/midx.c +16 -15
  80. data/vendor/libgit2/src/libgit2/mwindow.c +5 -2
  81. data/vendor/libgit2/src/libgit2/mwindow.h +4 -1
  82. data/vendor/libgit2/src/libgit2/notes.c +5 -5
  83. data/vendor/libgit2/src/libgit2/object.c +89 -25
  84. data/vendor/libgit2/src/libgit2/object.h +12 -3
  85. data/vendor/libgit2/src/libgit2/odb.c +194 -50
  86. data/vendor/libgit2/src/libgit2/odb.h +43 -4
  87. data/vendor/libgit2/src/libgit2/odb_loose.c +128 -70
  88. data/vendor/libgit2/src/libgit2/odb_pack.c +96 -44
  89. data/vendor/libgit2/src/libgit2/oid.c +134 -76
  90. data/vendor/libgit2/src/libgit2/oid.h +183 -9
  91. data/vendor/libgit2/src/libgit2/pack-objects.c +15 -4
  92. data/vendor/libgit2/src/libgit2/pack.c +90 -66
  93. data/vendor/libgit2/src/libgit2/pack.h +29 -15
  94. data/vendor/libgit2/src/libgit2/parse.c +4 -3
  95. data/vendor/libgit2/src/libgit2/patch_parse.c +5 -5
  96. data/vendor/libgit2/src/libgit2/push.c +13 -3
  97. data/vendor/libgit2/src/libgit2/reader.c +1 -1
  98. data/vendor/libgit2/src/libgit2/rebase.c +19 -18
  99. data/vendor/libgit2/src/libgit2/refdb_fs.c +70 -39
  100. data/vendor/libgit2/src/libgit2/reflog.c +7 -5
  101. data/vendor/libgit2/src/libgit2/reflog.h +1 -2
  102. data/vendor/libgit2/src/libgit2/refs.c +2 -0
  103. data/vendor/libgit2/src/libgit2/remote.c +38 -37
  104. data/vendor/libgit2/src/libgit2/remote.h +40 -0
  105. data/vendor/libgit2/src/libgit2/repository.c +212 -36
  106. data/vendor/libgit2/src/libgit2/repository.h +9 -0
  107. data/vendor/libgit2/src/libgit2/reset.c +2 -2
  108. data/vendor/libgit2/src/libgit2/revert.c +4 -4
  109. data/vendor/libgit2/src/libgit2/revparse.c +23 -7
  110. data/vendor/libgit2/src/libgit2/revwalk.c +5 -1
  111. data/vendor/libgit2/src/libgit2/stash.c +201 -26
  112. data/vendor/libgit2/src/libgit2/strarray.c +1 -0
  113. data/vendor/libgit2/src/libgit2/strarray.h +25 -0
  114. data/vendor/libgit2/src/libgit2/streams/openssl.c +1 -1
  115. data/vendor/libgit2/src/libgit2/streams/openssl_dynamic.c +7 -3
  116. data/vendor/libgit2/src/libgit2/streams/socket.c +4 -1
  117. data/vendor/libgit2/src/libgit2/submodule.c +6 -2
  118. data/vendor/libgit2/src/libgit2/sysdir.c +294 -7
  119. data/vendor/libgit2/src/libgit2/sysdir.h +39 -9
  120. data/vendor/libgit2/src/libgit2/tag.c +29 -10
  121. data/vendor/libgit2/src/libgit2/tag.h +2 -2
  122. data/vendor/libgit2/src/libgit2/threadstate.h +1 -1
  123. data/vendor/libgit2/src/libgit2/transports/http.c +8 -7
  124. data/vendor/libgit2/src/libgit2/transports/httpclient.c +9 -0
  125. data/vendor/libgit2/src/libgit2/transports/httpclient.h +10 -0
  126. data/vendor/libgit2/src/libgit2/transports/local.c +14 -0
  127. data/vendor/libgit2/src/libgit2/transports/smart.c +35 -0
  128. data/vendor/libgit2/src/libgit2/transports/smart.h +10 -1
  129. data/vendor/libgit2/src/libgit2/transports/smart_pkt.c +153 -41
  130. data/vendor/libgit2/src/libgit2/transports/smart_protocol.c +42 -12
  131. data/vendor/libgit2/src/libgit2/transports/ssh.c +62 -65
  132. data/vendor/libgit2/src/libgit2/transports/winhttp.c +9 -4
  133. data/vendor/libgit2/src/libgit2/tree-cache.c +4 -4
  134. data/vendor/libgit2/src/libgit2/tree.c +22 -16
  135. data/vendor/libgit2/src/libgit2/tree.h +2 -2
  136. data/vendor/libgit2/src/libgit2/worktree.c +5 -0
  137. data/vendor/libgit2/src/util/CMakeLists.txt +7 -1
  138. data/vendor/libgit2/src/util/fs_path.c +1 -1
  139. data/vendor/libgit2/src/util/futils.c +0 -3
  140. data/vendor/libgit2/src/util/git2_util.h +2 -2
  141. data/vendor/libgit2/src/util/hash/openssl.c +4 -3
  142. data/vendor/libgit2/src/util/hash/rfc6234/sha.h +0 -112
  143. data/vendor/libgit2/src/util/hash.h +13 -0
  144. data/vendor/libgit2/src/util/net.c +338 -84
  145. data/vendor/libgit2/src/util/net.h +7 -0
  146. data/vendor/libgit2/src/util/posix.h +2 -0
  147. data/vendor/libgit2/src/util/rand.c +4 -0
  148. data/vendor/libgit2/src/util/regexp.c +3 -3
  149. data/vendor/libgit2/src/util/thread.h +20 -19
  150. data/vendor/libgit2/src/util/util.h +1 -0
  151. metadata +7 -5
  152. data/vendor/libgit2/src/util/win32/findfile.c +0 -286
  153. data/vendor/libgit2/src/util/win32/findfile.h +0 -22
  154. /data/vendor/libgit2/src/{features.h.in → util/git2_features.h.in} +0 -0
@@ -32,6 +32,8 @@
32
32
  #define GIT_CAP_SYMREF "symref"
33
33
  #define GIT_CAP_WANT_TIP_SHA1 "allow-tip-sha1-in-want"
34
34
  #define GIT_CAP_WANT_REACHABLE_SHA1 "allow-reachable-sha1-in-want"
35
+ #define GIT_CAP_OBJECT_FORMAT "object-format="
36
+ #define GIT_CAP_AGENT "agent="
35
37
 
36
38
  extern bool git_smart__ofs_delta_enabled;
37
39
 
@@ -133,6 +135,8 @@ typedef struct transport_smart_caps {
133
135
  thin_pack:1,
134
136
  want_tip_sha1:1,
135
137
  want_reachable_sha1:1;
138
+ char *object_format;
139
+ char *agent;
136
140
  } transport_smart_caps;
137
141
 
138
142
  typedef int (*packetsize_cb)(size_t received, void *payload);
@@ -182,7 +186,12 @@ int git_smart__get_push_stream(transport_smart *t, git_smart_subtransport_stream
182
186
  int git_smart__update_heads(transport_smart *t, git_vector *symrefs);
183
187
 
184
188
  /* smart_pkt.c */
185
- int git_pkt_parse_line(git_pkt **head, const char **endptr, const char *line, size_t linelen);
189
+ typedef struct {
190
+ git_oid_t oid_type;
191
+ int seen_capabilities: 1;
192
+ } git_pkt_parse_data;
193
+
194
+ int git_pkt_parse_line(git_pkt **head, const char **endptr, const char *line, size_t linelen, git_pkt_parse_data *data);
186
195
  int git_pkt_buffer_flush(git_str *buf);
187
196
  int git_pkt_send_flush(GIT_SOCKET s);
188
197
  int git_pkt_buffer_done(git_str *buf);
@@ -12,6 +12,7 @@
12
12
  #include "netops.h"
13
13
  #include "posix.h"
14
14
  #include "str.h"
15
+ #include "oid.h"
15
16
 
16
17
  #include "git2/types.h"
17
18
  #include "git2/errors.h"
@@ -20,11 +21,14 @@
20
21
 
21
22
  #include <ctype.h>
22
23
 
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 ";
24
+ #define PKT_DONE_STR "0009done\n"
25
+ #define PKT_FLUSH_STR "0000"
26
+ #define PKT_HAVE_PREFIX "have "
27
+ #define PKT_WANT_PREFIX "want "
28
+
29
+ #define PKT_LEN_SIZE 4
30
+ #define PKT_MAX_SIZE 0xffff
31
+ #define PKT_MAX_WANTLEN (PKT_LEN_SIZE + CONST_STRLEN(PKT_WANT_PREFIX) + GIT_OID_MAX_HEXSIZE + 1)
28
32
 
29
33
  static int flush_pkt(git_pkt **out)
30
34
  {
@@ -53,10 +57,11 @@ static int ack_pkt(git_pkt **out, const char *line, size_t len)
53
57
  line += 4;
54
58
  len -= 4;
55
59
 
56
- if (len < GIT_OID_HEXSZ || git_oid_fromstr(&pkt->oid, line) < 0)
60
+ if (len < GIT_OID_SHA1_HEXSIZE ||
61
+ git_oid__fromstr(&pkt->oid, line, GIT_OID_SHA1) < 0)
57
62
  goto out_err;
58
- line += GIT_OID_HEXSZ;
59
- len -= GIT_OID_HEXSZ;
63
+ line += GIT_OID_SHA1_HEXSIZE;
64
+ len -= GIT_OID_SHA1_HEXSIZE;
60
65
 
61
66
  if (len && line[0] == ' ') {
62
67
  line++;
@@ -210,25 +215,87 @@ static int sideband_error_pkt(git_pkt **out, const char *line, size_t len)
210
215
  return 0;
211
216
  }
212
217
 
218
+ static int set_data(
219
+ git_pkt_parse_data *data,
220
+ const char *line,
221
+ size_t len)
222
+ {
223
+ const char *caps, *format_str = NULL, *eos;
224
+ size_t format_len;
225
+ git_oid_t remote_oid_type;
226
+
227
+ GIT_ASSERT_ARG(data);
228
+
229
+ if ((caps = memchr(line, '\0', len)) != NULL) {
230
+ caps++;
231
+
232
+ if (strncmp(caps, "object-format=", CONST_STRLEN("object-format=")) == 0)
233
+ format_str = caps + CONST_STRLEN("object-format=");
234
+ else if ((format_str = strstr(caps, " object-format=")) != NULL)
235
+ format_str += CONST_STRLEN(" object-format=");
236
+ }
237
+
238
+ if (format_str) {
239
+ if ((eos = strchr(format_str, ' ')) == NULL)
240
+ eos = strchr(format_str, '\0');
241
+
242
+ GIT_ASSERT(eos);
243
+
244
+ format_len = eos - format_str;
245
+
246
+ if ((remote_oid_type = git_oid_type_fromstrn(format_str, format_len)) == 0) {
247
+ git_error_set(GIT_ERROR_INVALID, "unknown remote object format '%.*s'", (int)format_len, format_str);
248
+ return -1;
249
+ }
250
+ } else {
251
+ remote_oid_type = GIT_OID_SHA1;
252
+ }
253
+
254
+ if (!data->oid_type) {
255
+ data->oid_type = remote_oid_type;
256
+ } else if (data->oid_type != remote_oid_type) {
257
+ git_error_set(GIT_ERROR_INVALID,
258
+ "the local object format '%s' does not match the remote object format '%s'",
259
+ git_oid_type_name(data->oid_type),
260
+ git_oid_type_name(remote_oid_type));
261
+ return -1;
262
+ }
263
+
264
+ return 0;
265
+ }
266
+
213
267
  /*
214
268
  * Parse an other-ref line.
215
269
  */
216
- static int ref_pkt(git_pkt **out, const char *line, size_t len)
270
+ static int ref_pkt(
271
+ git_pkt **out,
272
+ const char *line,
273
+ size_t len,
274
+ git_pkt_parse_data *data)
217
275
  {
218
276
  git_pkt_ref *pkt;
219
- size_t alloclen;
277
+ size_t alloclen, oid_hexsize;
220
278
 
221
279
  pkt = git__calloc(1, sizeof(git_pkt_ref));
222
280
  GIT_ERROR_CHECK_ALLOC(pkt);
223
281
  pkt->type = GIT_PKT_REF;
224
282
 
225
- if (len < GIT_OID_HEXSZ || git_oid_fromstr(&pkt->head.oid, line) < 0)
283
+ /* Determine OID type from capabilities */
284
+ if (!data->seen_capabilities && set_data(data, line, len) < 0)
285
+ return -1;
286
+
287
+ GIT_ASSERT(data->oid_type);
288
+ oid_hexsize = git_oid_hexsize(data->oid_type);
289
+
290
+ if (len < oid_hexsize ||
291
+ git_oid__fromstr(&pkt->head.oid, line, data->oid_type) < 0)
226
292
  goto out_err;
227
- line += GIT_OID_HEXSZ;
228
- len -= GIT_OID_HEXSZ;
293
+ line += oid_hexsize;
294
+ len -= oid_hexsize;
229
295
 
230
296
  if (git__prefixncmp(line, len, " "))
231
297
  goto out_err;
298
+
232
299
  line++;
233
300
  len--;
234
301
 
@@ -245,8 +312,14 @@ static int ref_pkt(git_pkt **out, const char *line, size_t len)
245
312
  memcpy(pkt->head.name, line, len);
246
313
  pkt->head.name[len] = '\0';
247
314
 
248
- if (strlen(pkt->head.name) < len)
249
- pkt->capabilities = strchr(pkt->head.name, '\0') + 1;
315
+ if (strlen(pkt->head.name) < len) {
316
+ if (!data->seen_capabilities)
317
+ pkt->capabilities = strchr(pkt->head.name, '\0') + 1;
318
+ else
319
+ goto out_err;
320
+ }
321
+
322
+ data->seen_capabilities = 1;
250
323
 
251
324
  *out = (git_pkt *)pkt;
252
325
  return 0;
@@ -415,7 +488,11 @@ static int parse_len(size_t *out, const char *line, size_t linelen)
415
488
  */
416
489
 
417
490
  int git_pkt_parse_line(
418
- git_pkt **pkt, const char **endptr, const char *line, size_t linelen)
491
+ git_pkt **pkt,
492
+ const char **endptr,
493
+ const char *line,
494
+ size_t linelen,
495
+ git_pkt_parse_data *data)
419
496
  {
420
497
  int error;
421
498
  size_t len;
@@ -490,7 +567,7 @@ int git_pkt_parse_line(
490
567
  else if (!git__prefixncmp(line, len, "unpack"))
491
568
  error = unpack_pkt(pkt, line, len);
492
569
  else
493
- error = ref_pkt(pkt, line, len);
570
+ error = ref_pkt(pkt, line, len, data);
494
571
 
495
572
  *endptr = line + len;
496
573
 
@@ -524,14 +601,21 @@ void git_pkt_free(git_pkt *pkt)
524
601
 
525
602
  int git_pkt_buffer_flush(git_str *buf)
526
603
  {
527
- return git_str_put(buf, pkt_flush_str, strlen(pkt_flush_str));
604
+ return git_str_put(buf, PKT_FLUSH_STR, CONST_STRLEN(PKT_FLUSH_STR));
528
605
  }
529
606
 
530
- static int buffer_want_with_caps(const git_remote_head *head, transport_smart_caps *caps, git_str *buf)
607
+ static int buffer_want_with_caps(
608
+ const git_remote_head *head,
609
+ transport_smart_caps *caps,
610
+ git_oid_t oid_type,
611
+ git_str *buf)
531
612
  {
532
613
  git_str str = GIT_STR_INIT;
533
- char oid[GIT_OID_HEXSZ +1] = {0};
534
- size_t len;
614
+ char oid[GIT_OID_MAX_HEXSIZE];
615
+ size_t oid_hexsize, len;
616
+
617
+ oid_hexsize = git_oid_hexsize(oid_type);
618
+ git_oid_fmt(oid, &head->oid);
535
619
 
536
620
  /* Prefer multi_ack_detailed */
537
621
  if (caps->multi_ack_detailed)
@@ -557,19 +641,20 @@ static int buffer_want_with_caps(const git_remote_head *head, transport_smart_ca
557
641
  if (git_str_oom(&str))
558
642
  return -1;
559
643
 
560
- len = strlen("XXXXwant ") + GIT_OID_HEXSZ + 1 /* NUL */ +
561
- git_str_len(&str) + 1 /* LF */;
562
-
563
- if (len > 0xffff) {
644
+ if (str.size > (PKT_MAX_SIZE - (PKT_MAX_WANTLEN + 1))) {
564
645
  git_error_set(GIT_ERROR_NET,
565
- "tried to produce packet with invalid length %" PRIuZ, len);
646
+ "tried to produce packet with invalid caps length %" PRIuZ, str.size);
566
647
  return -1;
567
648
  }
568
649
 
650
+ len = PKT_LEN_SIZE + CONST_STRLEN(PKT_WANT_PREFIX) +
651
+ oid_hexsize + 1 /* NUL */ +
652
+ git_str_len(&str) + 1 /* LF */;
653
+
569
654
  git_str_grow_by(buf, len);
570
- git_oid_fmt(oid, &head->oid);
571
655
  git_str_printf(buf,
572
- "%04xwant %s %s\n", (unsigned int)len, oid, git_str_cstr(&str));
656
+ "%04x%s%.*s %s\n", (unsigned int)len, PKT_WANT_PREFIX,
657
+ (int)oid_hexsize, oid, git_str_cstr(&str));
573
658
  git_str_dispose(&str);
574
659
 
575
660
  GIT_ERROR_CHECK_ALLOC_STR(buf);
@@ -588,8 +673,21 @@ int git_pkt_buffer_wants(
588
673
  transport_smart_caps *caps,
589
674
  git_str *buf)
590
675
  {
591
- size_t i = 0;
592
676
  const git_remote_head *head;
677
+ char oid[GIT_OID_MAX_HEXSIZE];
678
+ git_oid_t oid_type;
679
+ size_t oid_hexsize, want_len, i = 0;
680
+
681
+ #ifdef GIT_EXPERIMENTAL_SHA256
682
+ oid_type = count > 0 ? refs[0]->oid.type : GIT_OID_SHA1;
683
+ #else
684
+ oid_type = GIT_OID_SHA1;
685
+ #endif
686
+
687
+ oid_hexsize = git_oid_hexsize(oid_type);
688
+
689
+ want_len = PKT_LEN_SIZE + CONST_STRLEN(PKT_WANT_PREFIX) +
690
+ oid_hexsize + 1 /* LF */;
593
691
 
594
692
  if (caps->common) {
595
693
  for (; i < count; ++i) {
@@ -598,23 +696,24 @@ int git_pkt_buffer_wants(
598
696
  break;
599
697
  }
600
698
 
601
- if (buffer_want_with_caps(refs[i], caps, buf) < 0)
699
+ if (buffer_want_with_caps(refs[i], caps, oid_type, buf) < 0)
602
700
  return -1;
603
701
 
604
702
  i++;
605
703
  }
606
704
 
607
705
  for (; i < count; ++i) {
608
- char oid[GIT_OID_HEXSZ];
609
-
610
706
  head = refs[i];
707
+
611
708
  if (head->local)
612
709
  continue;
613
710
 
614
711
  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');
712
+
713
+ git_str_printf(buf, "%04x%s%.*s\n",
714
+ (unsigned int)want_len, PKT_WANT_PREFIX,
715
+ (int)oid_hexsize, oid);
716
+
618
717
  if (git_str_oom(buf))
619
718
  return -1;
620
719
  }
@@ -624,14 +723,27 @@ int git_pkt_buffer_wants(
624
723
 
625
724
  int git_pkt_buffer_have(git_oid *oid, git_str *buf)
626
725
  {
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);
726
+ char oid_str[GIT_OID_MAX_HEXSIZE];
727
+ git_oid_t oid_type;
728
+ size_t oid_hexsize, have_len;
729
+
730
+ #ifdef GIT_EXPERIMENTAL_SHA256
731
+ oid_type = oid->type;
732
+ #else
733
+ oid_type = GIT_OID_SHA1;
734
+ #endif
735
+
736
+ oid_hexsize = git_oid_hexsize(oid_type);
737
+ have_len = PKT_LEN_SIZE + CONST_STRLEN(PKT_HAVE_PREFIX) +
738
+ oid_hexsize + 1 /* LF */;
739
+
740
+ git_oid_fmt(oid_str, oid);
741
+ return git_str_printf(buf, "%04x%s%.*s\n",
742
+ (unsigned int)have_len, PKT_HAVE_PREFIX,
743
+ (int)oid_hexsize, oid_str);
632
744
  }
633
745
 
634
746
  int git_pkt_buffer_done(git_str *buf)
635
747
  {
636
- return git_str_puts(buf, pkt_done_str);
748
+ return git_str_put(buf, PKT_DONE_STR, CONST_STRLEN(PKT_DONE_STR));
637
749
  }
@@ -32,6 +32,7 @@ int git_smart__store_refs(transport_smart *t, int flushes)
32
32
  int error, flush = 0, recvd;
33
33
  const char *line_end = NULL;
34
34
  git_pkt *pkt = NULL;
35
+ git_pkt_parse_data pkt_parse_data = { 0 };
35
36
  size_t i;
36
37
 
37
38
  /* Clear existing refs in case git_remote_connect() is called again
@@ -45,7 +46,7 @@ int git_smart__store_refs(transport_smart *t, int flushes)
45
46
 
46
47
  do {
47
48
  if (buf->offset > 0)
48
- error = git_pkt_parse_line(&pkt, &line_end, buf->data, buf->offset);
49
+ error = git_pkt_parse_line(&pkt, &line_end, buf->data, buf->offset, &pkt_parse_data);
49
50
  else
50
51
  error = GIT_EBUFS;
51
52
 
@@ -133,9 +134,12 @@ on_invalid:
133
134
  return -1;
134
135
  }
135
136
 
136
- int git_smart__detect_caps(git_pkt_ref *pkt, transport_smart_caps *caps, git_vector *symrefs)
137
+ int git_smart__detect_caps(
138
+ git_pkt_ref *pkt,
139
+ transport_smart_caps *caps,
140
+ git_vector *symrefs)
137
141
  {
138
- const char *ptr;
142
+ const char *ptr, *start;
139
143
 
140
144
  /* No refs or capabilities, odd but not a problem */
141
145
  if (pkt == NULL || pkt->capabilities == NULL)
@@ -207,13 +211,35 @@ int git_smart__detect_caps(git_pkt_ref *pkt, transport_smart_caps *caps, git_vec
207
211
 
208
212
  if (!git__prefixcmp(ptr, GIT_CAP_WANT_TIP_SHA1)) {
209
213
  caps->common = caps->want_tip_sha1 = 1;
210
- ptr += strlen(GIT_CAP_DELETE_REFS);
214
+ ptr += strlen(GIT_CAP_WANT_TIP_SHA1);
211
215
  continue;
212
216
  }
213
217
 
214
218
  if (!git__prefixcmp(ptr, GIT_CAP_WANT_REACHABLE_SHA1)) {
215
219
  caps->common = caps->want_reachable_sha1 = 1;
216
- ptr += strlen(GIT_CAP_DELETE_REFS);
220
+ ptr += strlen(GIT_CAP_WANT_REACHABLE_SHA1);
221
+ continue;
222
+ }
223
+
224
+ if (!git__prefixcmp(ptr, GIT_CAP_OBJECT_FORMAT)) {
225
+ ptr += strlen(GIT_CAP_OBJECT_FORMAT);
226
+
227
+ start = ptr;
228
+ ptr = strchr(ptr, ' ');
229
+
230
+ if ((caps->object_format = git__strndup(start, (ptr - start))) == NULL)
231
+ return -1;
232
+ continue;
233
+ }
234
+
235
+ if (!git__prefixcmp(ptr, GIT_CAP_AGENT)) {
236
+ ptr += strlen(GIT_CAP_AGENT);
237
+
238
+ start = ptr;
239
+ ptr = strchr(ptr, ' ');
240
+
241
+ if ((caps->agent = git__strndup(start, (ptr - start))) == NULL)
242
+ return -1;
217
243
  continue;
218
244
  }
219
245
 
@@ -228,11 +254,12 @@ static int recv_pkt(git_pkt **out_pkt, git_pkt_type *out_type, gitno_buffer *buf
228
254
  {
229
255
  const char *ptr = buf->data, *line_end = ptr;
230
256
  git_pkt *pkt = NULL;
257
+ git_pkt_parse_data pkt_parse_data = { 0 };
231
258
  int error = 0, ret;
232
259
 
233
260
  do {
234
261
  if (buf->offset > 0)
235
- error = git_pkt_parse_line(&pkt, &line_end, ptr, buf->offset);
262
+ error = git_pkt_parse_line(&pkt, &line_end, ptr, buf->offset, &pkt_parse_data);
236
263
  else
237
264
  error = GIT_EBUFS;
238
265
 
@@ -643,12 +670,12 @@ static int gen_pktline(git_str *buf, git_push *push)
643
670
  {
644
671
  push_spec *spec;
645
672
  size_t i, len;
646
- char old_id[GIT_OID_HEXSZ+1], new_id[GIT_OID_HEXSZ+1];
673
+ char old_id[GIT_OID_SHA1_HEXSIZE+1], new_id[GIT_OID_SHA1_HEXSIZE+1];
647
674
 
648
- old_id[GIT_OID_HEXSZ] = '\0'; new_id[GIT_OID_HEXSZ] = '\0';
675
+ old_id[GIT_OID_SHA1_HEXSIZE] = '\0'; new_id[GIT_OID_SHA1_HEXSIZE] = '\0';
649
676
 
650
677
  git_vector_foreach(&push->specs, i, spec) {
651
- len = 2*GIT_OID_HEXSZ + 7 + strlen(spec->refspec.dst);
678
+ len = 2*GIT_OID_SHA1_HEXSIZE + 7 + strlen(spec->refspec.dst);
652
679
 
653
680
  if (i == 0) {
654
681
  ++len; /* '\0' */
@@ -723,6 +750,7 @@ static int add_push_report_pkt(git_push *push, git_pkt *pkt)
723
750
  static int add_push_report_sideband_pkt(git_push *push, git_pkt_data *data_pkt, git_str *data_pkt_buf)
724
751
  {
725
752
  git_pkt *pkt;
753
+ git_pkt_parse_data pkt_parse_data = { 0 };
726
754
  const char *line, *line_end = NULL;
727
755
  size_t line_len;
728
756
  int error;
@@ -741,7 +769,7 @@ static int add_push_report_sideband_pkt(git_push *push, git_pkt_data *data_pkt,
741
769
  }
742
770
 
743
771
  while (line_len > 0) {
744
- error = git_pkt_parse_line(&pkt, &line_end, line, line_len);
772
+ error = git_pkt_parse_line(&pkt, &line_end, line, line_len, &pkt_parse_data);
745
773
 
746
774
  if (error == GIT_EBUFS) {
747
775
  /* Buffer the data when the inner packet is split
@@ -777,6 +805,7 @@ done:
777
805
  static int parse_report(transport_smart *transport, git_push *push)
778
806
  {
779
807
  git_pkt *pkt = NULL;
808
+ git_pkt_parse_data pkt_parse_data = { 0 };
780
809
  const char *line_end = NULL;
781
810
  gitno_buffer *buf = &transport->buffer;
782
811
  int error, recvd;
@@ -785,7 +814,8 @@ static int parse_report(transport_smart *transport, git_push *push)
785
814
  for (;;) {
786
815
  if (buf->offset > 0)
787
816
  error = git_pkt_parse_line(&pkt, &line_end,
788
- buf->data, buf->offset);
817
+ buf->data, buf->offset,
818
+ &pkt_parse_data);
789
819
  else
790
820
  error = GIT_EBUFS;
791
821
 
@@ -1020,7 +1050,7 @@ int git_smart__push(git_transport *transport, git_push *push)
1020
1050
  #ifdef PUSH_DEBUG
1021
1051
  {
1022
1052
  git_remote_head *head;
1023
- char hex[GIT_OID_HEXSZ+1]; hex[GIT_OID_HEXSZ] = '\0';
1053
+ char hex[GIT_OID_SHA1_HEXSIZE+1]; hex[GIT_OID_SHA1_HEXSIZE] = '\0';
1024
1054
 
1025
1055
  git_vector_foreach(&push->remote->refs, i, head) {
1026
1056
  git_oid_fmt(hex, &head->oid);