rugged 1.5.1 → 1.6.2

Sign up to get free protection for your applications and to get access to all the features.
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);