rugged 1.6.5 → 1.7.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (182) hide show
  1. checksums.yaml +4 -4
  2. data/ext/rugged/rugged_allocator.c +0 -54
  3. data/lib/rugged/version.rb +1 -1
  4. data/vendor/libgit2/CMakeLists.txt +3 -8
  5. data/vendor/libgit2/cmake/CheckPrototypeDefinitionSafe.cmake +16 -0
  6. data/vendor/libgit2/cmake/SelectGSSAPI.cmake +3 -3
  7. data/vendor/libgit2/cmake/SelectHTTPSBackend.cmake +21 -2
  8. data/vendor/libgit2/cmake/SelectHashes.cmake +4 -0
  9. data/vendor/libgit2/cmake/SelectXdiff.cmake +9 -0
  10. data/vendor/libgit2/deps/pcre/LICENCE +5 -5
  11. data/vendor/libgit2/deps/pcre/pcre.h +2 -2
  12. data/vendor/libgit2/deps/pcre/pcre_compile.c +6 -3
  13. data/vendor/libgit2/deps/pcre/pcre_exec.c +2 -2
  14. data/vendor/libgit2/deps/xdiff/CMakeLists.txt +28 -0
  15. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/git-xdiff.h +4 -1
  16. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xdiffi.c +19 -18
  17. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xdiffi.h +2 -4
  18. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xemit.c +3 -3
  19. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xhistogram.c +7 -18
  20. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xmacros.h +18 -1
  21. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xmerge.c +24 -22
  22. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xpatience.c +21 -30
  23. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xprepare.c +13 -30
  24. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xutils.c +18 -1
  25. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xutils.h +2 -1
  26. data/vendor/libgit2/include/git2/common.h +26 -1
  27. data/vendor/libgit2/include/git2/diff.h +41 -3
  28. data/vendor/libgit2/include/git2/errors.h +4 -2
  29. data/vendor/libgit2/include/git2/index.h +9 -0
  30. data/vendor/libgit2/include/git2/oid.h +1 -1
  31. data/vendor/libgit2/include/git2/remote.h +18 -0
  32. data/vendor/libgit2/include/git2/repository.h +12 -2
  33. data/vendor/libgit2/include/git2/sys/alloc.h +0 -34
  34. data/vendor/libgit2/include/git2/sys/commit_graph.h +12 -2
  35. data/vendor/libgit2/include/git2/sys/midx.h +5 -1
  36. data/vendor/libgit2/include/git2/sys/stream.h +16 -2
  37. data/vendor/libgit2/include/git2/sys/transport.h +20 -2
  38. data/vendor/libgit2/include/git2/version.h +4 -4
  39. data/vendor/libgit2/include/git2/worktree.h +3 -1
  40. data/vendor/libgit2/src/CMakeLists.txt +34 -11
  41. data/vendor/libgit2/src/cli/cmd_clone.c +22 -6
  42. data/vendor/libgit2/src/cli/progress.c +9 -8
  43. data/vendor/libgit2/src/cli/progress.h +4 -4
  44. data/vendor/libgit2/src/libgit2/CMakeLists.txt +1 -19
  45. data/vendor/libgit2/src/libgit2/annotated_commit.c +2 -2
  46. data/vendor/libgit2/src/libgit2/annotated_commit.h +1 -1
  47. data/vendor/libgit2/src/libgit2/apply.c +4 -3
  48. data/vendor/libgit2/src/libgit2/blame.c +23 -16
  49. data/vendor/libgit2/src/libgit2/blame_git.c +0 -1
  50. data/vendor/libgit2/src/libgit2/branch.c +2 -2
  51. data/vendor/libgit2/src/libgit2/cherrypick.c +3 -3
  52. data/vendor/libgit2/src/libgit2/clone.c +3 -1
  53. data/vendor/libgit2/src/libgit2/commit.c +31 -9
  54. data/vendor/libgit2/src/libgit2/commit_graph.c +110 -43
  55. data/vendor/libgit2/src/libgit2/commit_graph.h +20 -4
  56. data/vendor/libgit2/src/libgit2/commit_list.c +12 -5
  57. data/vendor/libgit2/src/libgit2/commit_list.h +1 -0
  58. data/vendor/libgit2/src/libgit2/config_file.c +14 -8
  59. data/vendor/libgit2/src/libgit2/describe.c +10 -7
  60. data/vendor/libgit2/src/libgit2/diff.c +16 -7
  61. data/vendor/libgit2/src/libgit2/diff.h +6 -6
  62. data/vendor/libgit2/src/libgit2/diff_file.c +7 -7
  63. data/vendor/libgit2/src/libgit2/diff_generate.c +36 -15
  64. data/vendor/libgit2/src/libgit2/diff_parse.c +20 -4
  65. data/vendor/libgit2/src/libgit2/diff_print.c +26 -7
  66. data/vendor/libgit2/src/libgit2/diff_tform.c +4 -4
  67. data/vendor/libgit2/src/libgit2/diff_xdiff.h +1 -1
  68. data/vendor/libgit2/src/libgit2/email.c +4 -3
  69. data/vendor/libgit2/src/libgit2/errors.c +73 -18
  70. data/vendor/libgit2/src/libgit2/fetch.c +37 -9
  71. data/vendor/libgit2/src/libgit2/fetch.h +0 -2
  72. data/vendor/libgit2/src/libgit2/fetchhead.c +11 -9
  73. data/vendor/libgit2/src/libgit2/grafts.c +272 -0
  74. data/vendor/libgit2/src/libgit2/grafts.h +36 -0
  75. data/vendor/libgit2/src/libgit2/ident.c +3 -3
  76. data/vendor/libgit2/src/libgit2/index.c +325 -125
  77. data/vendor/libgit2/src/libgit2/index.h +14 -1
  78. data/vendor/libgit2/src/libgit2/indexer.c +10 -3
  79. data/vendor/libgit2/src/libgit2/iterator.c +20 -5
  80. data/vendor/libgit2/src/libgit2/iterator.h +3 -0
  81. data/vendor/libgit2/src/libgit2/libgit2.c +39 -0
  82. data/vendor/libgit2/src/libgit2/merge.c +14 -9
  83. data/vendor/libgit2/src/libgit2/merge_file.c +0 -2
  84. data/vendor/libgit2/src/libgit2/midx.c +66 -37
  85. data/vendor/libgit2/src/libgit2/midx.h +13 -3
  86. data/vendor/libgit2/src/libgit2/notes.c +9 -8
  87. data/vendor/libgit2/src/libgit2/object.c +40 -15
  88. data/vendor/libgit2/src/libgit2/object.h +6 -0
  89. data/vendor/libgit2/src/libgit2/odb.c +11 -5
  90. data/vendor/libgit2/src/libgit2/odb_pack.c +16 -3
  91. data/vendor/libgit2/src/libgit2/oid.c +7 -1
  92. data/vendor/libgit2/src/libgit2/oidarray.c +49 -3
  93. data/vendor/libgit2/src/libgit2/oidarray.h +5 -1
  94. data/vendor/libgit2/src/libgit2/pack-objects.c +19 -12
  95. data/vendor/libgit2/src/libgit2/pack-objects.h +5 -2
  96. data/vendor/libgit2/src/libgit2/pack.c +3 -3
  97. data/vendor/libgit2/src/libgit2/parse.c +7 -4
  98. data/vendor/libgit2/src/libgit2/parse.h +1 -1
  99. data/vendor/libgit2/src/libgit2/patch.h +7 -1
  100. data/vendor/libgit2/src/libgit2/patch_generate.c +24 -5
  101. data/vendor/libgit2/src/libgit2/patch_parse.c +16 -8
  102. data/vendor/libgit2/src/libgit2/push.c +2 -2
  103. data/vendor/libgit2/src/libgit2/reader.c +1 -1
  104. data/vendor/libgit2/src/libgit2/rebase.c +72 -84
  105. data/vendor/libgit2/src/libgit2/refdb_fs.c +22 -13
  106. data/vendor/libgit2/src/libgit2/refs.c +8 -1
  107. data/vendor/libgit2/src/libgit2/remote.c +15 -6
  108. data/vendor/libgit2/src/libgit2/remote.h +1 -0
  109. data/vendor/libgit2/src/libgit2/repository.c +580 -301
  110. data/vendor/libgit2/src/libgit2/repository.h +17 -2
  111. data/vendor/libgit2/src/libgit2/reset.c +2 -2
  112. data/vendor/libgit2/src/libgit2/revert.c +8 -11
  113. data/vendor/libgit2/src/libgit2/revparse.c +1 -4
  114. data/vendor/libgit2/src/libgit2/revwalk.c +26 -4
  115. data/vendor/libgit2/src/libgit2/stash.c +9 -8
  116. data/vendor/libgit2/src/libgit2/streams/mbedtls.c +0 -1
  117. data/vendor/libgit2/src/libgit2/streams/openssl.c +8 -16
  118. data/vendor/libgit2/src/libgit2/streams/schannel.c +715 -0
  119. data/vendor/libgit2/src/libgit2/streams/schannel.h +28 -0
  120. data/vendor/libgit2/src/libgit2/streams/socket.c +237 -51
  121. data/vendor/libgit2/src/libgit2/streams/socket.h +3 -1
  122. data/vendor/libgit2/src/libgit2/streams/stransport.c +40 -12
  123. data/vendor/libgit2/src/libgit2/streams/tls.c +5 -0
  124. data/vendor/libgit2/src/libgit2/submodule.h +3 -3
  125. data/vendor/libgit2/src/libgit2/threadstate.c +15 -2
  126. data/vendor/libgit2/src/libgit2/threadstate.h +1 -3
  127. data/vendor/libgit2/src/libgit2/transports/auth.h +1 -2
  128. data/vendor/libgit2/src/libgit2/transports/{auth_negotiate.c → auth_gssapi.c} +32 -32
  129. data/vendor/libgit2/src/libgit2/transports/auth_negotiate.h +1 -1
  130. data/vendor/libgit2/src/libgit2/transports/auth_ntlm.h +1 -1
  131. data/vendor/libgit2/src/libgit2/transports/{auth_ntlm.c → auth_ntlmclient.c} +12 -12
  132. data/vendor/libgit2/src/libgit2/transports/auth_sspi.c +341 -0
  133. data/vendor/libgit2/src/libgit2/transports/git.c +7 -8
  134. data/vendor/libgit2/src/libgit2/transports/http.c +7 -2
  135. data/vendor/libgit2/src/libgit2/transports/httpclient.c +5 -0
  136. data/vendor/libgit2/src/libgit2/transports/local.c +13 -4
  137. data/vendor/libgit2/src/libgit2/transports/smart.c +33 -27
  138. data/vendor/libgit2/src/libgit2/transports/smart.h +23 -8
  139. data/vendor/libgit2/src/libgit2/transports/smart_pkt.c +136 -17
  140. data/vendor/libgit2/src/libgit2/transports/smart_protocol.c +154 -47
  141. data/vendor/libgit2/src/libgit2/transports/ssh.c +3 -3
  142. data/vendor/libgit2/src/libgit2/transports/winhttp.c +14 -15
  143. data/vendor/libgit2/src/libgit2/tree-cache.c +26 -16
  144. data/vendor/libgit2/src/libgit2/tree-cache.h +5 -3
  145. data/vendor/libgit2/src/libgit2/tree.c +1 -1
  146. data/vendor/libgit2/src/libgit2/worktree.c +25 -10
  147. data/vendor/libgit2/src/util/alloc.c +65 -6
  148. data/vendor/libgit2/src/util/alloc.h +34 -9
  149. data/vendor/libgit2/src/util/allocators/failalloc.c +0 -60
  150. data/vendor/libgit2/src/util/allocators/failalloc.h +0 -6
  151. data/vendor/libgit2/src/util/allocators/stdalloc.c +2 -105
  152. data/vendor/libgit2/src/util/allocators/win32_leakcheck.c +0 -68
  153. data/vendor/libgit2/src/util/array.h +6 -1
  154. data/vendor/libgit2/src/util/cc-compat.h +2 -0
  155. data/vendor/libgit2/src/util/filebuf.c +6 -1
  156. data/vendor/libgit2/src/util/filebuf.h +19 -6
  157. data/vendor/libgit2/src/util/fs_path.c +1 -1
  158. data/vendor/libgit2/src/util/futils.c +8 -5
  159. data/vendor/libgit2/src/util/git2_features.h.in +9 -3
  160. data/vendor/libgit2/src/util/net.c +308 -157
  161. data/vendor/libgit2/src/util/net.h +25 -0
  162. data/vendor/libgit2/src/util/posix.c +54 -0
  163. data/vendor/libgit2/src/util/posix.h +22 -0
  164. data/vendor/libgit2/src/util/rand.c +6 -4
  165. data/vendor/libgit2/src/util/staticstr.h +66 -0
  166. data/vendor/libgit2/src/util/util.c +15 -10
  167. data/vendor/libgit2/src/util/util.h +24 -16
  168. data/vendor/libgit2/src/util/win32/error.c +1 -1
  169. data/vendor/libgit2/src/util/win32/path_w32.c +8 -8
  170. data/vendor/libgit2/src/util/win32/posix_w32.c +1 -1
  171. data/vendor/libgit2/src/util/win32/utf-conv.c +73 -75
  172. data/vendor/libgit2/src/util/win32/utf-conv.h +81 -14
  173. data/vendor/libgit2/src/util/win32/w32_util.c +1 -1
  174. metadata +29 -23
  175. data/vendor/libgit2/cmake/SelectWinHTTP.cmake +0 -17
  176. data/vendor/libgit2/src/libgit2/netops.c +0 -124
  177. data/vendor/libgit2/src/libgit2/netops.h +0 -68
  178. /data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xdiff.h +0 -0
  179. /data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xemit.h +0 -0
  180. /data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xinclude.h +0 -0
  181. /data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xprepare.h +0 -0
  182. /data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xtypes.h +0 -0
@@ -108,15 +108,13 @@ int git_object__from_raw(
108
108
  return 0;
109
109
  }
110
110
 
111
- int git_object__from_odb_object(
111
+ int git_object__init_from_odb_object(
112
112
  git_object **object_out,
113
113
  git_repository *repo,
114
114
  git_odb_object *odb_obj,
115
115
  git_object_t type)
116
116
  {
117
- int error;
118
117
  size_t object_size;
119
- git_object_def *def;
120
118
  git_object *object = NULL;
121
119
 
122
120
  GIT_ASSERT_ARG(object_out);
@@ -143,6 +141,23 @@ int git_object__from_odb_object(
143
141
  object->cached.size = odb_obj->cached.size;
144
142
  object->repo = repo;
145
143
 
144
+ *object_out = object;
145
+ return 0;
146
+ }
147
+
148
+ int git_object__from_odb_object(
149
+ git_object **object_out,
150
+ git_repository *repo,
151
+ git_odb_object *odb_obj,
152
+ git_object_t type)
153
+ {
154
+ int error;
155
+ git_object_def *def;
156
+ git_object *object = NULL;
157
+
158
+ if ((error = git_object__init_from_odb_object(&object, repo, odb_obj, type)) < 0)
159
+ return error;
160
+
146
161
  /* Parse raw object data */
147
162
  def = &git_objects_table[odb_obj->cached.type];
148
163
  GIT_ASSERT(def->free && def->parse);
@@ -181,6 +196,7 @@ int git_object_lookup_prefix(
181
196
  git_object *object = NULL;
182
197
  git_odb *odb = NULL;
183
198
  git_odb_object *odb_obj = NULL;
199
+ size_t oid_hexsize;
184
200
  int error = 0;
185
201
 
186
202
  GIT_ASSERT_ARG(repo);
@@ -196,10 +212,12 @@ int git_object_lookup_prefix(
196
212
  if (error < 0)
197
213
  return error;
198
214
 
199
- if (len > GIT_OID_SHA1_HEXSIZE)
200
- len = GIT_OID_SHA1_HEXSIZE;
215
+ oid_hexsize = git_oid_hexsize(repo->oid_type);
201
216
 
202
- if (len == GIT_OID_SHA1_HEXSIZE) {
217
+ if (len > oid_hexsize)
218
+ len = oid_hexsize;
219
+
220
+ if (len == oid_hexsize) {
203
221
  git_cached_obj *cached = NULL;
204
222
 
205
223
  /* We want to match the full id : we can first look up in the cache,
@@ -233,8 +251,9 @@ int git_object_lookup_prefix(
233
251
  error = git_odb_read(&odb_obj, odb, id);
234
252
  }
235
253
  } else {
236
- git_oid short_oid = GIT_OID_SHA1_ZERO;
254
+ git_oid short_oid;
237
255
 
256
+ git_oid_clear(&short_oid, repo->oid_type);
238
257
  git_oid__cpy_prefix(&short_oid, id, len);
239
258
 
240
259
  /* If len < GIT_OID_SHA1_HEXSIZE (a strict short oid was given), we have
@@ -262,7 +281,8 @@ int git_object_lookup_prefix(
262
281
  }
263
282
 
264
283
  int git_object_lookup(git_object **object_out, git_repository *repo, const git_oid *id, git_object_t type) {
265
- return git_object_lookup_prefix(object_out, repo, id, GIT_OID_SHA1_HEXSIZE, type);
284
+ return git_object_lookup_prefix(object_out,
285
+ repo, id, git_oid_hexsize(repo->oid_type), type);
266
286
  }
267
287
 
268
288
  void git_object_free(git_object *object)
@@ -503,31 +523,36 @@ cleanup:
503
523
  static int git_object__short_id(git_str *out, const git_object *obj)
504
524
  {
505
525
  git_repository *repo;
506
- int len = GIT_ABBREV_DEFAULT, error;
507
- git_oid id = GIT_OID_SHA1_ZERO;
526
+ git_oid id;
508
527
  git_odb *odb;
528
+ size_t oid_hexsize;
529
+ int len = GIT_ABBREV_DEFAULT, error;
509
530
 
510
531
  GIT_ASSERT_ARG(out);
511
532
  GIT_ASSERT_ARG(obj);
512
533
 
513
534
  repo = git_object_owner(obj);
514
535
 
536
+ git_oid_clear(&id, repo->oid_type);
537
+ oid_hexsize = git_oid_hexsize(repo->oid_type);
538
+
515
539
  if ((error = git_repository__configmap_lookup(&len, repo, GIT_CONFIGMAP_ABBREV)) < 0)
516
540
  return error;
517
541
 
542
+ if (len < 0 || (size_t)len > oid_hexsize) {
543
+ git_error_set(GIT_ERROR_CONFIG, "invalid oid abbreviation setting: '%d'", len);
544
+ return -1;
545
+ }
546
+
518
547
  if ((error = git_repository_odb(&odb, repo)) < 0)
519
548
  return error;
520
549
 
521
- while (len < GIT_OID_SHA1_HEXSIZE) {
550
+ while ((size_t)len < oid_hexsize) {
522
551
  /* set up short oid */
523
552
  memcpy(&id.id, &obj->cached.oid.id, (len + 1) / 2);
524
553
  if (len & 1)
525
554
  id.id[len / 2] &= 0xf0;
526
555
 
527
- #ifdef GIT_EXPERIMENTAL_SHA256
528
- id.type = GIT_OID_SHA1;
529
- #endif
530
-
531
556
  error = git_odb_exists_prefix(NULL, odb, &id, len);
532
557
  if (error != GIT_EAMBIGUOUS)
533
558
  break;
@@ -36,6 +36,12 @@ int git_object__from_raw(
36
36
  git_object_t object_type,
37
37
  git_oid_t oid_type);
38
38
 
39
+ int git_object__init_from_odb_object(
40
+ git_object **object_out,
41
+ git_repository *repo,
42
+ git_odb_object *odb_obj,
43
+ git_object_t type);
44
+
39
45
  int git_object__from_odb_object(
40
46
  git_object **object_out,
41
47
  git_repository *repo,
@@ -748,7 +748,8 @@ int git_odb__add_default_backends(
748
748
  git_error_set(GIT_ERROR_ODB, "failed to acquire the odb lock");
749
749
  return -1;
750
750
  }
751
- if (!db->cgraph && git_commit_graph_new(&db->cgraph, objects_dir, false) < 0) {
751
+ if (!db->cgraph &&
752
+ git_commit_graph_new(&db->cgraph, objects_dir, false, db->options.oid_type) < 0) {
752
753
  git_mutex_unlock(&db->lock);
753
754
  return -1;
754
755
  }
@@ -1493,11 +1494,16 @@ static int read_prefix_1(git_odb_object **out, git_odb *db,
1493
1494
 
1494
1495
  if (found && git_oid__cmp(&full_oid, &found_full_oid)) {
1495
1496
  git_str buf = GIT_STR_INIT;
1497
+ const char *idstr;
1496
1498
 
1497
- git_str_printf(&buf, "multiple matches for prefix: %s",
1498
- git_oid_tostr_s(&full_oid));
1499
- git_str_printf(&buf, " %s",
1500
- git_oid_tostr_s(&found_full_oid));
1499
+ if ((idstr = git_oid_tostr_s(&full_oid)) == NULL) {
1500
+ git_str_puts(&buf, "failed to parse object id");
1501
+ } else {
1502
+ git_str_printf(&buf, "multiple matches for prefix: %s", idstr);
1503
+
1504
+ if ((idstr = git_oid_tostr_s(&found_full_oid)) != NULL)
1505
+ git_str_printf(&buf, " %s", idstr);
1506
+ }
1501
1507
 
1502
1508
  error = git_odb__error_ambiguous(buf.ptr);
1503
1509
  git_str_dispose(&buf);
@@ -309,11 +309,17 @@ static int pack_entry_find_prefix(
309
309
  {
310
310
  int error;
311
311
  size_t i;
312
- git_oid found_full_oid = GIT_OID_SHA1_ZERO;
312
+ git_oid found_full_oid;
313
313
  bool found = false;
314
314
  struct git_pack_file *last_found = backend->last_found, *p;
315
315
  git_midx_entry midx_entry;
316
316
 
317
+ #ifdef GIT_EXPERIMENTAL_SHA256
318
+ git_oid_clear(&found_full_oid, short_oid->type);
319
+ #else
320
+ git_oid_clear(&found_full_oid, GIT_OID_SHA1);
321
+ #endif
322
+
317
323
  if (backend->midx) {
318
324
  error = git_midx_entry_find(&midx_entry, backend->midx, short_oid, len);
319
325
  if (error == GIT_EAMBIGUOUS)
@@ -473,7 +479,9 @@ static int refresh_multi_pack_index(struct pack_backend *backend)
473
479
  }
474
480
  }
475
481
 
476
- error = git_midx_open(&backend->midx, git_str_cstr(&midx_path));
482
+ error = git_midx_open(&backend->midx, git_str_cstr(&midx_path),
483
+ backend->opts.oid_type);
484
+
477
485
  git_str_dispose(&midx_path);
478
486
  if (error < 0)
479
487
  return error;
@@ -792,7 +800,12 @@ static int pack_backend__writemidx(git_odb_backend *_backend)
792
800
 
793
801
  backend = (struct pack_backend *)_backend;
794
802
 
795
- error = git_midx_writer_new(&w, backend->pack_folder);
803
+ error = git_midx_writer_new(&w, backend->pack_folder
804
+ #ifdef GIT_EXPERIMENTAL_SHA256
805
+ , backend->opts.oid_type
806
+ #endif
807
+ );
808
+
796
809
  if (error < 0)
797
810
  return error;
798
811
 
@@ -155,7 +155,13 @@ int git_oid_pathfmt(char *str, const git_oid *oid)
155
155
 
156
156
  char *git_oid_tostr_s(const git_oid *oid)
157
157
  {
158
- char *str = GIT_THREADSTATE->oid_fmt;
158
+ git_threadstate *threadstate = git_threadstate_get();
159
+ char *str;
160
+
161
+ if (!threadstate)
162
+ return NULL;
163
+
164
+ str = threadstate->oid_fmt;
159
165
  git_oid_nfmt(str, git_oid_hexsize(git_oid_type(oid)) + 1, oid);
160
166
  return str;
161
167
  }
@@ -15,10 +15,17 @@ void git_oidarray_dispose(git_oidarray *arr)
15
15
  git__free(arr->ids);
16
16
  }
17
17
 
18
- void git_oidarray__from_array(git_oidarray *arr, git_array_oid_t *array)
18
+ void git_oidarray__from_array(git_oidarray *out, const git_array_oid_t *array)
19
19
  {
20
- arr->count = array->size;
21
- arr->ids = array->ptr;
20
+ out->count = array->size;
21
+ out->ids = array->ptr;
22
+ }
23
+
24
+ void git_oidarray__to_array(git_array_oid_t *out, const git_oidarray *array)
25
+ {
26
+ out->ptr = array->ids;
27
+ out->size = array->count;
28
+ out->asize = array->count;
22
29
  }
23
30
 
24
31
  void git_oidarray__reverse(git_oidarray *arr)
@@ -33,6 +40,45 @@ void git_oidarray__reverse(git_oidarray *arr)
33
40
  }
34
41
  }
35
42
 
43
+ int git_oidarray__add(git_array_oid_t *arr, git_oid *id)
44
+ {
45
+ git_oid *add, *iter;
46
+ size_t i;
47
+
48
+ git_array_foreach(*arr, i, iter) {
49
+ if (git_oid_cmp(iter, id) == 0)
50
+ return 0;
51
+ }
52
+
53
+ if ((add = git_array_alloc(*arr)) == NULL)
54
+ return -1;
55
+
56
+ git_oid_cpy(add, id);
57
+ return 0;
58
+ }
59
+
60
+ bool git_oidarray__remove(git_array_oid_t *arr, git_oid *id)
61
+ {
62
+ bool found = false;
63
+ size_t remain, i;
64
+ git_oid *iter;
65
+
66
+ git_array_foreach(*arr, i, iter) {
67
+ if (git_oid_cmp(iter, id) == 0) {
68
+ arr->size--;
69
+ remain = arr->size - i;
70
+
71
+ if (remain > 0)
72
+ memmove(&arr->ptr[i], &arr->ptr[i+1], remain * sizeof(git_oid));
73
+
74
+ found = true;
75
+ break;
76
+ }
77
+ }
78
+
79
+ return found;
80
+ }
81
+
36
82
  #ifndef GIT_DEPRECATE_HARD
37
83
 
38
84
  void git_oidarray_free(git_oidarray *arr)
@@ -15,6 +15,10 @@
15
15
  typedef git_array_t(git_oid) git_array_oid_t;
16
16
 
17
17
  extern void git_oidarray__reverse(git_oidarray *arr);
18
- extern void git_oidarray__from_array(git_oidarray *arr, git_array_oid_t *array);
18
+ extern void git_oidarray__from_array(git_oidarray *out, const git_array_oid_t *array);
19
+ extern void git_oidarray__to_array(git_array_oid_t *out, const git_oidarray *array);
20
+
21
+ int git_oidarray__add(git_array_oid_t *arr, git_oid *id);
22
+ bool git_oidarray__remove(git_array_oid_t *arr, git_oid *id);
19
23
 
20
24
  #endif
@@ -11,7 +11,6 @@
11
11
  #include "zstream.h"
12
12
  #include "delta.h"
13
13
  #include "iterator.h"
14
- #include "netops.h"
15
14
  #include "pack.h"
16
15
  #include "thread.h"
17
16
  #include "tree.h"
@@ -127,6 +126,7 @@ out:
127
126
 
128
127
  int git_packbuilder_new(git_packbuilder **out, git_repository *repo)
129
128
  {
129
+ git_hash_algorithm_t hash_algorithm;
130
130
  git_packbuilder *pb;
131
131
 
132
132
  *out = NULL;
@@ -134,6 +134,11 @@ int git_packbuilder_new(git_packbuilder **out, git_repository *repo)
134
134
  pb = git__calloc(1, sizeof(*pb));
135
135
  GIT_ERROR_CHECK_ALLOC(pb);
136
136
 
137
+ pb->oid_type = repo->oid_type;
138
+
139
+ hash_algorithm = git_oid_algorithm(pb->oid_type);
140
+ GIT_ASSERT(hash_algorithm);
141
+
137
142
  if (git_oidmap_new(&pb->object_ix) < 0 ||
138
143
  git_oidmap_new(&pb->walk_objects) < 0 ||
139
144
  git_pool_init(&pb->object_pool, sizeof(struct walk_object)) < 0)
@@ -142,7 +147,7 @@ int git_packbuilder_new(git_packbuilder **out, git_repository *repo)
142
147
  pb->repo = repo;
143
148
  pb->nr_threads = 1; /* do not spawn any thread by default */
144
149
 
145
- if (git_hash_ctx_init(&pb->ctx, GIT_HASH_ALGORITHM_SHA1) < 0 ||
150
+ if (git_hash_ctx_init(&pb->ctx, hash_algorithm) < 0 ||
146
151
  git_zstream_init(&pb->zstream, GIT_ZSTREAM_DEFLATE) < 0 ||
147
152
  git_repository_odb(&pb->odb, repo) < 0 ||
148
153
  packbuilder_config(pb) < 0)
@@ -249,10 +254,10 @@ int git_packbuilder_insert(git_packbuilder *pb, const git_oid *oid,
249
254
  pb->done = false;
250
255
 
251
256
  if (pb->progress_cb) {
252
- double current_time = git__timer();
253
- double elapsed = current_time - pb->last_progress_report_time;
257
+ uint64_t current_time = git_time_monotonic();
258
+ uint64_t elapsed = current_time - pb->last_progress_report_time;
254
259
 
255
- if (elapsed < 0 || elapsed >= MIN_PROGRESS_UPDATE_INTERVAL) {
260
+ if (elapsed >= MIN_PROGRESS_UPDATE_INTERVAL) {
256
261
  pb->last_progress_report_time = current_time;
257
262
 
258
263
  ret = pb->progress_cb(
@@ -315,9 +320,11 @@ static int write_object(
315
320
  git_object_t type;
316
321
  unsigned char hdr[10], *zbuf = NULL;
317
322
  void *data = NULL;
318
- size_t hdr_len, zbuf_len = COMPRESS_BUFLEN, data_len;
323
+ size_t hdr_len, zbuf_len = COMPRESS_BUFLEN, data_len, oid_size;
319
324
  int error;
320
325
 
326
+ oid_size = git_oid_size(pb->oid_type);
327
+
321
328
  /*
322
329
  * If we have a delta base, let's use the delta to save space.
323
330
  * Otherwise load the whole object. 'data' ends up pointing to
@@ -347,8 +354,8 @@ static int write_object(
347
354
  goto done;
348
355
 
349
356
  if (type == GIT_OBJECT_REF_DELTA) {
350
- if ((error = write_cb(po->delta->id.id, GIT_OID_SHA1_SIZE, cb_data)) < 0 ||
351
- (error = git_hash_update(&pb->ctx, po->delta->id.id, GIT_OID_SHA1_SIZE)) < 0)
357
+ if ((error = write_cb(po->delta->id.id, oid_size, cb_data)) < 0 ||
358
+ (error = git_hash_update(&pb->ctx, po->delta->id.id, oid_size)) < 0)
352
359
  goto done;
353
360
  }
354
361
 
@@ -668,7 +675,7 @@ static int write_pack(git_packbuilder *pb,
668
675
  if ((error = git_hash_final(entry_oid.id, &pb->ctx)) < 0)
669
676
  goto done;
670
677
 
671
- error = write_cb(entry_oid.id, GIT_OID_SHA1_SIZE, cb_data);
678
+ error = write_cb(entry_oid.id, git_oid_size(pb->oid_type), cb_data);
672
679
 
673
680
  done:
674
681
  /* if callback cancelled writing, we must still free delta_data */
@@ -926,10 +933,10 @@ static int report_delta_progress(
926
933
  int ret;
927
934
 
928
935
  if (pb->progress_cb) {
929
- double current_time = git__timer();
930
- double elapsed = current_time - pb->last_progress_report_time;
936
+ uint64_t current_time = git_time_monotonic();
937
+ uint64_t elapsed = current_time - pb->last_progress_report_time;
931
938
 
932
- if (force || elapsed < 0 || elapsed >= MIN_PROGRESS_UPDATE_INTERVAL) {
939
+ if (force || elapsed >= MIN_PROGRESS_UPDATE_INTERVAL) {
933
940
  pb->last_progress_report_time = current_time;
934
941
 
935
942
  ret = pb->progress_cb(
@@ -13,7 +13,6 @@
13
13
  #include "str.h"
14
14
  #include "hash.h"
15
15
  #include "oidmap.h"
16
- #include "netops.h"
17
16
  #include "zstream.h"
18
17
  #include "pool.h"
19
18
  #include "indexer.h"
@@ -56,6 +55,8 @@ struct git_packbuilder {
56
55
  git_repository *repo; /* associated repository */
57
56
  git_odb *odb; /* associated object database */
58
57
 
58
+ git_oid_t oid_type;
59
+
59
60
  git_hash_ctx ctx;
60
61
  git_zstream zstream;
61
62
 
@@ -94,7 +95,9 @@ struct git_packbuilder {
94
95
 
95
96
  git_packbuilder_progress progress_cb;
96
97
  void *progress_cb_payload;
97
- double last_progress_report_time; /* the time progress was last reported */
98
+
99
+ /* the time progress was last reported, in millisecond ticks */
100
+ uint64_t last_progress_report_time;
98
101
 
99
102
  bool done;
100
103
  };
@@ -1268,13 +1268,13 @@ static off64_t nth_packed_object_offset_locked(struct git_pack_file *p, uint32_t
1268
1268
  end = index + p->index_map.len;
1269
1269
  index += 4 * 256;
1270
1270
  if (p->index_version == 1)
1271
- return ntohl(*((uint32_t *)(index + (p->oid_size + 4) * n)));
1271
+ return ntohl(*((uint32_t *)(index + (p->oid_size + 4) * (size_t) n)));
1272
1272
 
1273
- index += 8 + p->num_objects * (p->oid_size + 4);
1273
+ index += 8 + (size_t) p->num_objects * (p->oid_size + 4);
1274
1274
  off32 = ntohl(*((uint32_t *)(index + 4 * n)));
1275
1275
  if (!(off32 & 0x80000000))
1276
1276
  return off32;
1277
- index += p->num_objects * 4 + (off32 & 0x7fffffff) * 8;
1277
+ index += (size_t) p->num_objects * 4 + (off32 & 0x7fffffff) * 8;
1278
1278
 
1279
1279
  /* Make sure we're not being sent out of bounds */
1280
1280
  if (index >= end - 8)
@@ -102,13 +102,16 @@ int git_parse_advance_digit(int64_t *out, git_parse_ctx *ctx, int base)
102
102
  return 0;
103
103
  }
104
104
 
105
- int git_parse_advance_oid(git_oid *out, git_parse_ctx *ctx)
105
+ int git_parse_advance_oid(git_oid *out, git_parse_ctx *ctx, git_oid_t oid_type)
106
106
  {
107
- if (ctx->line_len < GIT_OID_SHA1_HEXSIZE)
107
+ size_t oid_hexsize = git_oid_hexsize(oid_type);
108
+ GIT_ASSERT(oid_hexsize);
109
+
110
+ if (ctx->line_len < oid_hexsize)
108
111
  return -1;
109
- if ((git_oid__fromstrn(out, ctx->line, GIT_OID_SHA1_HEXSIZE, GIT_OID_SHA1)) < 0)
112
+ if ((git_oid__fromstrn(out, ctx->line, oid_hexsize, oid_type)) < 0)
110
113
  return -1;
111
- git_parse_advance_chars(ctx, GIT_OID_SHA1_HEXSIZE);
114
+ git_parse_advance_chars(ctx, oid_hexsize);
112
115
  return 0;
113
116
  }
114
117
 
@@ -50,7 +50,7 @@ int git_parse_advance_expected(
50
50
  int git_parse_advance_ws(git_parse_ctx *ctx);
51
51
  int git_parse_advance_nl(git_parse_ctx *ctx);
52
52
  int git_parse_advance_digit(int64_t *out, git_parse_ctx *ctx, int base);
53
- int git_parse_advance_oid(git_oid *out, git_parse_ctx *ctx);
53
+ int git_parse_advance_oid(git_oid *out, git_parse_ctx *ctx, git_oid_t oid_type);
54
54
 
55
55
  enum GIT_PARSE_PEEK_FLAGS {
56
56
  GIT_PARSE_PEEK_SKIP_WHITESPACE = (1 << 0)
@@ -59,9 +59,15 @@ typedef struct {
59
59
  * This prefix will be removed when looking for files. The default is 1.
60
60
  */
61
61
  uint32_t prefix_len;
62
+
63
+ /**
64
+ * The type of object IDs in the patch file. The default is
65
+ * `GIT_OID_DEFAULT`.
66
+ */
67
+ git_oid_t oid_type;
62
68
  } git_patch_options;
63
69
 
64
- #define GIT_PATCH_OPTIONS_INIT { 1 }
70
+ #define GIT_PATCH_OPTIONS_INIT { 1, GIT_OID_DEFAULT }
65
71
 
66
72
  extern int git_patch__to_buf(git_str *out, git_patch *patch);
67
73
  extern void git_patch_free(git_patch *patch);
@@ -81,7 +81,8 @@ static void patch_generated_init_common(git_patch_generated *patch)
81
81
 
82
82
  static int patch_generated_normalize_options(
83
83
  git_diff_options *out,
84
- const git_diff_options *opts)
84
+ const git_diff_options *opts,
85
+ git_repository *repo)
85
86
  {
86
87
  if (opts) {
87
88
  GIT_ERROR_CHECK_VERSION(opts, GIT_DIFF_OPTIONS_VERSION, "git_diff_options");
@@ -91,6 +92,23 @@ static int patch_generated_normalize_options(
91
92
  memcpy(out, &default_opts, sizeof(git_diff_options));
92
93
  }
93
94
 
95
+ if (repo && opts && opts->oid_type && repo->oid_type != opts->oid_type) {
96
+ /*
97
+ * This limitation feels unnecessary - we should consider
98
+ * allowing users to generate diffs with a different object
99
+ * ID format than the repository.
100
+ */
101
+ git_error_set(GIT_ERROR_INVALID,
102
+ "specified object ID type does not match repository object ID type");
103
+ return -1;
104
+ } else if (repo) {
105
+ out->oid_type = repo->oid_type;
106
+ } else if (opts && opts->oid_type) {
107
+ out->oid_type = opts->oid_type;
108
+ } else {
109
+ out->oid_type = GIT_OID_DEFAULT;
110
+ }
111
+
94
112
  out->old_prefix = opts && opts->old_prefix ?
95
113
  git__strdup(opts->old_prefix) :
96
114
  git__strdup(DIFF_OLD_PREFIX_DEFAULT);
@@ -118,7 +136,7 @@ static int patch_generated_init(
118
136
  patch->delta_index = delta_index;
119
137
 
120
138
  if ((error = patch_generated_normalize_options(
121
- &patch->base.diff_opts, &diff->opts)) < 0 ||
139
+ &patch->base.diff_opts, &diff->opts, diff->repo)) < 0 ||
122
140
  (error = git_diff_file_content__init_from_diff(
123
141
  &patch->ofile, diff, patch->base.delta, true)) < 0 ||
124
142
  (error = git_diff_file_content__init_from_diff(
@@ -449,7 +467,7 @@ static int patch_generated_from_sources(
449
467
  git_xdiff_output *xo,
450
468
  git_diff_file_content_src *oldsrc,
451
469
  git_diff_file_content_src *newsrc,
452
- const git_diff_options *opts)
470
+ const git_diff_options *given_opts)
453
471
  {
454
472
  int error = 0;
455
473
  git_repository *repo =
@@ -457,11 +475,12 @@ static int patch_generated_from_sources(
457
475
  newsrc->blob ? git_blob_owner(newsrc->blob) : NULL;
458
476
  git_diff_file *lfile = &pd->delta.old_file, *rfile = &pd->delta.new_file;
459
477
  git_diff_file_content *ldata = &pd->patch.ofile, *rdata = &pd->patch.nfile;
478
+ git_diff_options *opts = &pd->patch.base.diff_opts;
460
479
 
461
- if ((error = patch_generated_normalize_options(&pd->patch.base.diff_opts, opts)) < 0)
480
+ if ((error = patch_generated_normalize_options(opts, given_opts, repo)) < 0)
462
481
  return error;
463
482
 
464
- if (opts && (opts->flags & GIT_DIFF_REVERSE) != 0) {
483
+ if ((opts->flags & GIT_DIFF_REVERSE) != 0) {
465
484
  void *tmp = lfile; lfile = rfile; rfile = tmp;
466
485
  tmp = ldata; ldata = rdata; rdata = tmp;
467
486
  }
@@ -166,15 +166,19 @@ static int parse_header_oid(
166
166
  uint16_t *oid_len,
167
167
  git_patch_parse_ctx *ctx)
168
168
  {
169
- size_t len;
169
+ size_t hexsize, len;
170
+
171
+ hexsize = git_oid_hexsize(ctx->opts.oid_type);
170
172
 
171
- for (len = 0; len < ctx->parse_ctx.line_len && len < GIT_OID_SHA1_HEXSIZE; len++) {
173
+ for (len = 0;
174
+ len < ctx->parse_ctx.line_len && len < hexsize;
175
+ len++) {
172
176
  if (!git__isxdigit(ctx->parse_ctx.line[len]))
173
177
  break;
174
178
  }
175
179
 
176
- if (len < GIT_OID_MINPREFIXLEN || len > GIT_OID_SHA1_HEXSIZE ||
177
- git_oid__fromstrn(oid, ctx->parse_ctx.line, len, GIT_OID_SHA1) < 0)
180
+ if (len < GIT_OID_MINPREFIXLEN || len > hexsize ||
181
+ git_oid__fromstrn(oid, ctx->parse_ctx.line, len, ctx->opts.oid_type) < 0)
178
182
  return git_parse_err("invalid hex formatted object id at line %"PRIuZ,
179
183
  ctx->parse_ctx.line_num);
180
184
 
@@ -1065,12 +1069,14 @@ static int check_patch(git_patch_parsed *patch)
1065
1069
  return git_parse_err("patch with no hunks");
1066
1070
 
1067
1071
  if (delta->status == GIT_DELTA_ADDED) {
1068
- git_oid_clear(&delta->old_file.id, GIT_OID_SHA1);
1072
+ git_oid_clear(&delta->old_file.id,
1073
+ patch->base.diff_opts.oid_type);
1069
1074
  delta->old_file.id_abbrev = 0;
1070
1075
  }
1071
1076
 
1072
1077
  if (delta->status == GIT_DELTA_DELETED) {
1073
- git_oid_clear(&delta->new_file.id, GIT_OID_SHA1);
1078
+ git_oid_clear(&delta->new_file.id,
1079
+ patch->base.diff_opts.oid_type);
1074
1080
  delta->new_file.id_abbrev = 0;
1075
1081
  }
1076
1082
 
@@ -1187,11 +1193,13 @@ int git_patch_parse(
1187
1193
  patch->base.delta->status = GIT_DELTA_MODIFIED;
1188
1194
  patch->base.delta->nfiles = 2;
1189
1195
 
1196
+ patch->base.diff_opts.oid_type = ctx->opts.oid_type;
1197
+
1190
1198
  start = ctx->parse_ctx.remain_len;
1191
1199
 
1192
1200
  if ((error = parse_patch_header(patch, ctx)) < 0 ||
1193
- (error = parse_patch_body(patch, ctx)) < 0 ||
1194
- (error = check_patch(patch)) < 0)
1201
+ (error = parse_patch_body(patch, ctx)) < 0 ||
1202
+ (error = check_patch(patch)) < 0)
1195
1203
  goto done;
1196
1204
 
1197
1205
  used = start - ctx->parse_ctx.remain_len;
@@ -118,8 +118,8 @@ static int parse_refspec(git_push *push, push_spec **spec, const char *str)
118
118
  s = git__calloc(1, sizeof(*s));
119
119
  GIT_ERROR_CHECK_ALLOC(s);
120
120
 
121
- git_oid_clear(&s->loid, GIT_OID_SHA1);
122
- git_oid_clear(&s->roid, GIT_OID_SHA1);
121
+ git_oid_clear(&s->loid, push->repo->oid_type);
122
+ git_oid_clear(&s->roid, push->repo->oid_type);
123
123
 
124
124
  if (git_refspec__parse(&s->refspec, str, false) < 0) {
125
125
  git_error_set(GIT_ERROR_INVALID, "invalid refspec %s", str);
@@ -125,7 +125,7 @@ static int workdir_reader_read(
125
125
  goto done;
126
126
 
127
127
  if (out_id || reader->index) {
128
- if ((error = git_odb__hash(&id, out->ptr, out->size, GIT_OBJECT_BLOB, GIT_OID_SHA1)) < 0)
128
+ if ((error = git_odb__hash(&id, out->ptr, out->size, GIT_OBJECT_BLOB, reader->repo->oid_type)) < 0)
129
129
  goto done;
130
130
  }
131
131