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
@@ -105,11 +105,12 @@ int git_odb__format_object_header(
105
105
  return 0;
106
106
  }
107
107
 
108
- int git_odb__hashobj(git_oid *id, git_rawobj *obj)
108
+ int git_odb__hashobj(git_oid *id, git_rawobj *obj, git_oid_t oid_type)
109
109
  {
110
110
  git_str_vec vec[2];
111
111
  char header[64];
112
112
  size_t hdrlen;
113
+ git_hash_algorithm_t algorithm;
113
114
  int error;
114
115
 
115
116
  GIT_ASSERT_ARG(id);
@@ -120,6 +121,11 @@ int git_odb__hashobj(git_oid *id, git_rawobj *obj)
120
121
  return -1;
121
122
  }
122
123
 
124
+ if (!(algorithm = git_oid_algorithm(oid_type))) {
125
+ git_error_set(GIT_ERROR_INVALID, "unknown oid type");
126
+ return -1;
127
+ }
128
+
123
129
  if (!obj->data && obj->len != 0) {
124
130
  git_error_set(GIT_ERROR_INVALID, "invalid object");
125
131
  return -1;
@@ -134,7 +140,11 @@ int git_odb__hashobj(git_oid *id, git_rawobj *obj)
134
140
  vec[1].data = obj->data;
135
141
  vec[1].len = obj->len;
136
142
 
137
- return git_hash_vec(id->id, vec, 2, GIT_HASH_ALGORITHM_SHA1);
143
+ #ifdef GIT_EXPERIMENTAL_SHA256
144
+ id->type = oid_type;
145
+ #endif
146
+
147
+ return git_hash_vec(id->id, vec, 2, algorithm);
138
148
  }
139
149
 
140
150
 
@@ -195,24 +205,35 @@ void git_odb_object_free(git_odb_object *object)
195
205
  git_cached_obj_decref(object);
196
206
  }
197
207
 
198
- int git_odb__hashfd(git_oid *out, git_file fd, size_t size, git_object_t type)
208
+ int git_odb__hashfd(
209
+ git_oid *out,
210
+ git_file fd,
211
+ size_t size,
212
+ git_object_t object_type,
213
+ git_oid_t oid_type)
199
214
  {
200
215
  size_t hdr_len;
201
216
  char hdr[64], buffer[GIT_BUFSIZE_FILEIO];
202
217
  git_hash_ctx ctx;
218
+ git_hash_algorithm_t algorithm;
203
219
  ssize_t read_len = 0;
204
220
  int error = 0;
205
221
 
206
- if (!git_object_typeisloose(type)) {
222
+ if (!git_object_typeisloose(object_type)) {
207
223
  git_error_set(GIT_ERROR_INVALID, "invalid object type for hash");
208
224
  return -1;
209
225
  }
210
226
 
211
- if ((error = git_hash_ctx_init(&ctx, GIT_HASH_ALGORITHM_SHA1)) < 0)
227
+ if (!(algorithm = git_oid_algorithm(oid_type))) {
228
+ git_error_set(GIT_ERROR_INVALID, "unknown oid type");
229
+ return -1;
230
+ }
231
+
232
+ if ((error = git_hash_ctx_init(&ctx, algorithm)) < 0)
212
233
  return error;
213
234
 
214
235
  if ((error = git_odb__format_object_header(&hdr_len, hdr,
215
- sizeof(hdr), size, type)) < 0)
236
+ sizeof(hdr), size, object_type)) < 0)
216
237
  goto done;
217
238
 
218
239
  if ((error = git_hash_update(&ctx, hdr, hdr_len)) < 0)
@@ -237,19 +258,28 @@ int git_odb__hashfd(git_oid *out, git_file fd, size_t size, git_object_t type)
237
258
 
238
259
  error = git_hash_final(out->id, &ctx);
239
260
 
261
+ #ifdef GIT_EXPERIMENTAL_SHA256
262
+ out->type = oid_type;
263
+ #endif
264
+
240
265
  done:
241
266
  git_hash_ctx_cleanup(&ctx);
242
267
  return error;
243
268
  }
244
269
 
245
270
  int git_odb__hashfd_filtered(
246
- git_oid *out, git_file fd, size_t size, git_object_t type, git_filter_list *fl)
271
+ git_oid *out,
272
+ git_file fd,
273
+ size_t size,
274
+ git_object_t object_type,
275
+ git_oid_t oid_type,
276
+ git_filter_list *fl)
247
277
  {
248
278
  int error;
249
279
  git_str raw = GIT_STR_INIT;
250
280
 
251
281
  if (!fl)
252
- return git_odb__hashfd(out, fd, size, type);
282
+ return git_odb__hashfd(out, fd, size, object_type, oid_type);
253
283
 
254
284
  /* size of data is used in header, so we have to read the whole file
255
285
  * into memory to apply filters before beginning to calculate the hash
@@ -261,7 +291,7 @@ int git_odb__hashfd_filtered(
261
291
  error = git_filter_list__convert_buf(&post, fl, &raw);
262
292
 
263
293
  if (!error)
264
- error = git_odb_hash(out, post.ptr, post.size, type);
294
+ error = git_odb__hash(out, post.ptr, post.size, object_type, oid_type);
265
295
 
266
296
  git_str_dispose(&post);
267
297
  }
@@ -269,7 +299,7 @@ int git_odb__hashfd_filtered(
269
299
  return error;
270
300
  }
271
301
 
272
- int git_odb__hashlink(git_oid *out, const char *path)
302
+ int git_odb__hashlink(git_oid *out, const char *path, git_oid_t oid_type)
273
303
  {
274
304
  struct stat st;
275
305
  int size;
@@ -303,20 +333,24 @@ int git_odb__hashlink(git_oid *out, const char *path)
303
333
  GIT_ASSERT(read_len <= size);
304
334
  link_data[read_len] = '\0';
305
335
 
306
- result = git_odb_hash(out, link_data, read_len, GIT_OBJECT_BLOB);
336
+ result = git_odb__hash(out, link_data, read_len, GIT_OBJECT_BLOB, oid_type);
307
337
  git__free(link_data);
308
338
  } else {
309
339
  int fd = git_futils_open_ro(path);
310
340
  if (fd < 0)
311
341
  return -1;
312
- result = git_odb__hashfd(out, fd, size, GIT_OBJECT_BLOB);
342
+ result = git_odb__hashfd(out, fd, size, GIT_OBJECT_BLOB, oid_type);
313
343
  p_close(fd);
314
344
  }
315
345
 
316
346
  return result;
317
347
  }
318
348
 
319
- int git_odb_hashfile(git_oid *out, const char *path, git_object_t type)
349
+ int git_odb__hashfile(
350
+ git_oid *out,
351
+ const char *path,
352
+ git_object_t object_type,
353
+ git_oid_t oid_type)
320
354
  {
321
355
  uint64_t size;
322
356
  int fd, error = 0;
@@ -333,14 +367,38 @@ int git_odb_hashfile(git_oid *out, const char *path, git_object_t type)
333
367
  goto done;
334
368
  }
335
369
 
336
- error = git_odb__hashfd(out, fd, (size_t)size, type);
370
+ error = git_odb__hashfd(out, fd, (size_t)size, object_type, oid_type);
337
371
 
338
372
  done:
339
373
  p_close(fd);
340
374
  return error;
341
375
  }
342
376
 
343
- int git_odb_hash(git_oid *id, const void *data, size_t len, git_object_t type)
377
+ #ifdef GIT_EXPERIMENTAL_SHA256
378
+ int git_odb_hashfile(
379
+ git_oid *out,
380
+ const char *path,
381
+ git_object_t object_type,
382
+ git_oid_t oid_type)
383
+ {
384
+ return git_odb__hashfile(out, path, object_type, oid_type);
385
+ }
386
+ #else
387
+ int git_odb_hashfile(
388
+ git_oid *out,
389
+ const char *path,
390
+ git_object_t object_type)
391
+ {
392
+ return git_odb__hashfile(out, path, object_type, GIT_OID_SHA1);
393
+ }
394
+ #endif
395
+
396
+ int git_odb__hash(
397
+ git_oid *id,
398
+ const void *data,
399
+ size_t len,
400
+ git_object_t object_type,
401
+ git_oid_t oid_type)
344
402
  {
345
403
  git_rawobj raw;
346
404
 
@@ -348,10 +406,31 @@ int git_odb_hash(git_oid *id, const void *data, size_t len, git_object_t type)
348
406
 
349
407
  raw.data = (void *)data;
350
408
  raw.len = len;
351
- raw.type = type;
409
+ raw.type = object_type;
352
410
 
353
- return git_odb__hashobj(id, &raw);
411
+ return git_odb__hashobj(id, &raw, oid_type);
412
+ }
413
+
414
+ #ifdef GIT_EXPERIMENTAL_SHA256
415
+ int git_odb_hash(
416
+ git_oid *out,
417
+ const void *data,
418
+ size_t len,
419
+ git_object_t object_type,
420
+ git_oid_t oid_type)
421
+ {
422
+ return git_odb__hash(out, data, len, object_type, oid_type);
423
+ }
424
+ #else
425
+ int git_odb_hash(
426
+ git_oid *out,
427
+ const void *data,
428
+ size_t len,
429
+ git_object_t type)
430
+ {
431
+ return git_odb__hash(out, data, len, type, GIT_OID_SHA1);
354
432
  }
433
+ #endif
355
434
 
356
435
  /**
357
436
  * FAKE WSTREAM
@@ -442,11 +521,28 @@ static int backend_sort_cmp(const void *a, const void *b)
442
521
  return (backend_b->priority - backend_a->priority);
443
522
  }
444
523
 
445
- int git_odb_new(git_odb **out)
524
+ static void normalize_options(
525
+ git_odb_options *opts,
526
+ const git_odb_options *given_opts)
527
+ {
528
+ git_odb_options init = GIT_ODB_OPTIONS_INIT;
529
+
530
+ if (given_opts)
531
+ memcpy(opts, given_opts, sizeof(git_odb_options));
532
+ else
533
+ memcpy(opts, &init, sizeof(git_odb_options));
534
+
535
+ if (!opts->oid_type)
536
+ opts->oid_type = GIT_OID_DEFAULT;
537
+ }
538
+
539
+ int git_odb__new(git_odb **out, const git_odb_options *opts)
446
540
  {
447
541
  git_odb *db = git__calloc(1, sizeof(*db));
448
542
  GIT_ERROR_CHECK_ALLOC(db);
449
543
 
544
+ normalize_options(&db->options, opts);
545
+
450
546
  if (git_mutex_init(&db->lock) < 0) {
451
547
  git__free(db);
452
548
  return -1;
@@ -468,6 +564,18 @@ int git_odb_new(git_odb **out)
468
564
  return 0;
469
565
  }
470
566
 
567
+ #ifdef GIT_EXPERIMENTAL_SHA256
568
+ int git_odb_new(git_odb **out, const git_odb_options *opts)
569
+ {
570
+ return git_odb__new(out, opts);
571
+ }
572
+ #else
573
+ int git_odb_new(git_odb **out)
574
+ {
575
+ return git_odb__new(out, NULL);
576
+ }
577
+ #endif
578
+
471
579
  static int add_backend_internal(
472
580
  git_odb *odb, git_odb_backend *backend,
473
581
  int priority, bool is_alternate, ino_t disk_inode)
@@ -575,6 +683,8 @@ int git_odb__add_default_backends(
575
683
  struct stat st;
576
684
  ino_t inode;
577
685
  git_odb_backend *loose, *packed;
686
+ git_odb_backend_loose_options loose_opts = GIT_ODB_BACKEND_LOOSE_OPTIONS_INIT;
687
+ git_odb_backend_pack_options pack_opts = GIT_ODB_BACKEND_PACK_OPTIONS_INIT;
578
688
 
579
689
  /* TODO: inodes are not really relevant on Win32, so we need to find
580
690
  * a cross-platform workaround for this */
@@ -609,14 +719,29 @@ int git_odb__add_default_backends(
609
719
  git_mutex_unlock(&db->lock);
610
720
  #endif
611
721
 
722
+ if (db->do_fsync)
723
+ loose_opts.flags |= GIT_ODB_BACKEND_LOOSE_FSYNC;
724
+
725
+ loose_opts.oid_type = db->options.oid_type;
726
+ pack_opts.oid_type = db->options.oid_type;
727
+
612
728
  /* add the loose object backend */
613
- if (git_odb_backend_loose(&loose, objects_dir, -1, db->do_fsync, 0, 0) < 0 ||
729
+ if (git_odb__backend_loose(&loose, objects_dir, &loose_opts) < 0 ||
614
730
  add_backend_internal(db, loose, git_odb__loose_priority, as_alternates, inode) < 0)
615
731
  return -1;
616
732
 
617
733
  /* add the packed file backend */
618
- if (git_odb_backend_pack(&packed, objects_dir) < 0 ||
619
- add_backend_internal(db, packed, git_odb__packed_priority, as_alternates, inode) < 0)
734
+ #ifdef GIT_EXPERIMENTAL_SHA256
735
+ if (git_odb_backend_pack(&packed, objects_dir, &pack_opts) < 0)
736
+ return -1;
737
+ #else
738
+ GIT_UNUSED(pack_opts);
739
+
740
+ if (git_odb_backend_pack(&packed, objects_dir) < 0)
741
+ return -1;
742
+ #endif
743
+
744
+ if (add_backend_internal(db, packed, git_odb__packed_priority, as_alternates, inode) < 0)
620
745
  return -1;
621
746
 
622
747
  if (git_mutex_lock(&db->lock) < 0) {
@@ -707,7 +832,10 @@ int git_odb_set_commit_graph(git_odb *odb, git_commit_graph *cgraph)
707
832
  return error;
708
833
  }
709
834
 
710
- int git_odb_open(git_odb **out, const char *objects_dir)
835
+ int git_odb__open(
836
+ git_odb **out,
837
+ const char *objects_dir,
838
+ const git_odb_options *opts)
711
839
  {
712
840
  git_odb *db;
713
841
 
@@ -716,7 +844,7 @@ int git_odb_open(git_odb **out, const char *objects_dir)
716
844
 
717
845
  *out = NULL;
718
846
 
719
- if (git_odb_new(&db) < 0)
847
+ if (git_odb__new(&db, opts) < 0)
720
848
  return -1;
721
849
 
722
850
  if (git_odb__add_default_backends(db, objects_dir, 0, 0) < 0) {
@@ -914,7 +1042,7 @@ static int odb_exists_prefix_1(git_oid *out, git_odb *db,
914
1042
  {
915
1043
  size_t i;
916
1044
  int error = GIT_ENOTFOUND, num_found = 0;
917
- git_oid last_found = {{0}}, found;
1045
+ git_oid last_found = GIT_OID_NONE, found;
918
1046
 
919
1047
  if ((error = git_mutex_lock(&db->lock)) < 0) {
920
1048
  git_error_set(GIT_ERROR_ODB, "failed to acquire the odb lock");
@@ -965,7 +1093,7 @@ int git_odb_exists_prefix(
965
1093
  git_oid *out, git_odb *db, const git_oid *short_id, size_t len)
966
1094
  {
967
1095
  int error;
968
- git_oid key = {{0}};
1096
+ git_oid key = GIT_OID_NONE;
969
1097
 
970
1098
  GIT_ASSERT_ARG(db);
971
1099
  GIT_ASSERT_ARG(short_id);
@@ -973,7 +1101,7 @@ int git_odb_exists_prefix(
973
1101
  if (len < GIT_OID_MINPREFIXLEN)
974
1102
  return git_odb__error_ambiguous("prefix length too short");
975
1103
 
976
- if (len >= GIT_OID_HEXSZ) {
1104
+ if (len >= git_oid_hexsize(db->options.oid_type)) {
977
1105
  if (git_odb_exists(db, short_id)) {
978
1106
  if (out)
979
1107
  git_oid_cpy(out, short_id);
@@ -1002,11 +1130,13 @@ int git_odb_expand_ids(
1002
1130
  git_odb_expand_id *ids,
1003
1131
  size_t count)
1004
1132
  {
1005
- size_t i;
1133
+ size_t hex_size, i;
1006
1134
 
1007
1135
  GIT_ASSERT_ARG(db);
1008
1136
  GIT_ASSERT_ARG(ids);
1009
1137
 
1138
+ hex_size = git_oid_hexsize(db->options.oid_type);
1139
+
1010
1140
  for (i = 0; i < count; i++) {
1011
1141
  git_odb_expand_id *query = &ids[i];
1012
1142
  int error = GIT_EAMBIGUOUS;
@@ -1015,13 +1145,13 @@ int git_odb_expand_ids(
1015
1145
  query->type = GIT_OBJECT_ANY;
1016
1146
 
1017
1147
  /* if we have a short OID, expand it first */
1018
- if (query->length >= GIT_OID_MINPREFIXLEN && query->length < GIT_OID_HEXSZ) {
1148
+ if (query->length >= GIT_OID_MINPREFIXLEN && query->length < hex_size) {
1019
1149
  git_oid actual_id;
1020
1150
 
1021
1151
  error = odb_exists_prefix_1(&actual_id, db, &query->id, query->length, false);
1022
1152
  if (!error) {
1023
1153
  git_oid_cpy(&query->id, &actual_id);
1024
- query->length = GIT_OID_HEXSZ;
1154
+ query->length = (unsigned short)hex_size;
1025
1155
  }
1026
1156
  }
1027
1157
 
@@ -1029,7 +1159,7 @@ int git_odb_expand_ids(
1029
1159
  * now we ought to have a 40-char OID, either because we've expanded it
1030
1160
  * or because the user passed a full OID. Ensure its type is right.
1031
1161
  */
1032
- if (query->length >= GIT_OID_HEXSZ) {
1162
+ if (query->length >= hex_size) {
1033
1163
  git_object_t actual_type;
1034
1164
 
1035
1165
  error = odb_otype_fast(&actual_type, db, &query->id);
@@ -1049,7 +1179,7 @@ int git_odb_expand_ids(
1049
1179
  /* the object is missing or ambiguous */
1050
1180
  case GIT_ENOTFOUND:
1051
1181
  case GIT_EAMBIGUOUS:
1052
- memset(&query->id, 0, sizeof(git_oid));
1182
+ git_oid_clear(&query->id, db->options.oid_type);
1053
1183
  query->length = 0;
1054
1184
  query->type = 0;
1055
1185
  break;
@@ -1157,7 +1287,7 @@ int git_odb__read_header_or_object(
1157
1287
  error = odb_read_header_1(len_p, type_p, db, id, true);
1158
1288
 
1159
1289
  if (error == GIT_ENOTFOUND)
1160
- return git_odb__error_notfound("cannot read header for", id, GIT_OID_HEXSZ);
1290
+ return git_odb__error_notfound("cannot read header for", id, git_oid_hexsize(db->options.oid_type));
1161
1291
 
1162
1292
  /* we found the header; return early */
1163
1293
  if (!error)
@@ -1179,8 +1309,11 @@ int git_odb__read_header_or_object(
1179
1309
  return error;
1180
1310
  }
1181
1311
 
1182
- static int odb_read_1(git_odb_object **out, git_odb *db, const git_oid *id,
1183
- bool only_refreshed)
1312
+ static int odb_read_1(
1313
+ git_odb_object **out,
1314
+ git_odb *db,
1315
+ const git_oid *id,
1316
+ bool only_refreshed)
1184
1317
  {
1185
1318
  size_t i;
1186
1319
  git_rawobj raw;
@@ -1224,7 +1357,7 @@ static int odb_read_1(git_odb_object **out, git_odb *db, const git_oid *id,
1224
1357
  return GIT_ENOTFOUND;
1225
1358
 
1226
1359
  if (git_odb__strict_hash_verification) {
1227
- if ((error = git_odb_hash(&hashed, raw.data, raw.len, raw.type)) < 0)
1360
+ if ((error = git_odb__hash(&hashed, raw.data, raw.len, raw.type, db->options.oid_type)) < 0)
1228
1361
  goto out;
1229
1362
 
1230
1363
  if (!git_oid_equal(id, &hashed)) {
@@ -1268,7 +1401,7 @@ int git_odb_read(git_odb_object **out, git_odb *db, const git_oid *id)
1268
1401
  error = odb_read_1(out, db, id, true);
1269
1402
 
1270
1403
  if (error == GIT_ENOTFOUND)
1271
- return git_odb__error_notfound("no match for id", id, GIT_OID_HEXSZ);
1404
+ return git_odb__error_notfound("no match for id", id, git_oid_hexsize(git_oid_type(id)));
1272
1405
 
1273
1406
  return error;
1274
1407
  }
@@ -1305,7 +1438,7 @@ static int read_prefix_1(git_odb_object **out, git_odb *db,
1305
1438
  {
1306
1439
  size_t i;
1307
1440
  int error = 0;
1308
- git_oid found_full_oid = {{0}};
1441
+ git_oid found_full_oid = GIT_OID_NONE;
1309
1442
  git_rawobj raw = {0};
1310
1443
  void *data = NULL;
1311
1444
  bool found = false;
@@ -1365,7 +1498,7 @@ static int read_prefix_1(git_odb_object **out, git_odb *db,
1365
1498
  if (git_odb__strict_hash_verification) {
1366
1499
  git_oid hash;
1367
1500
 
1368
- if ((error = git_odb_hash(&hash, raw.data, raw.len, raw.type)) < 0)
1501
+ if ((error = git_odb__hash(&hash, raw.data, raw.len, raw.type, db->options.oid_type)) < 0)
1369
1502
  goto out;
1370
1503
 
1371
1504
  if (!git_oid_equal(&found_full_oid, &hash)) {
@@ -1391,19 +1524,22 @@ out:
1391
1524
  int git_odb_read_prefix(
1392
1525
  git_odb_object **out, git_odb *db, const git_oid *short_id, size_t len)
1393
1526
  {
1394
- git_oid key = {{0}};
1527
+ git_oid key = GIT_OID_NONE;
1528
+ size_t hex_size;
1395
1529
  int error;
1396
1530
 
1397
1531
  GIT_ASSERT_ARG(out);
1398
1532
  GIT_ASSERT_ARG(db);
1399
1533
 
1534
+ hex_size = git_oid_hexsize(db->options.oid_type);
1535
+
1400
1536
  if (len < GIT_OID_MINPREFIXLEN)
1401
1537
  return git_odb__error_ambiguous("prefix length too short");
1402
1538
 
1403
- if (len > GIT_OID_HEXSZ)
1404
- len = GIT_OID_HEXSZ;
1539
+ if (len > hex_size)
1540
+ len = hex_size;
1405
1541
 
1406
- if (len == GIT_OID_HEXSZ) {
1542
+ if (len == hex_size) {
1407
1543
  *out = git_cache_get_raw(odb_cache(db), short_id);
1408
1544
  if (*out != NULL)
1409
1545
  return 0;
@@ -1463,7 +1599,7 @@ int git_odb_write(
1463
1599
  GIT_ASSERT_ARG(oid);
1464
1600
  GIT_ASSERT_ARG(db);
1465
1601
 
1466
- if ((error = git_odb_hash(oid, data, len, type)) < 0)
1602
+ if ((error = git_odb__hash(oid, data, len, type, db->options.oid_type)) < 0)
1467
1603
  return error;
1468
1604
 
1469
1605
  if (git_oid_is_zero(oid))
@@ -1564,10 +1700,13 @@ int git_odb_open_wstream(
1564
1700
  ctx = git__malloc(sizeof(git_hash_ctx));
1565
1701
  GIT_ERROR_CHECK_ALLOC(ctx);
1566
1702
 
1567
- if ((error = git_hash_ctx_init(ctx, GIT_HASH_ALGORITHM_SHA1)) < 0 ||
1568
- (error = hash_header(ctx, size, type)) < 0)
1703
+ if ((error = git_hash_ctx_init(ctx, git_oid_algorithm(db->options.oid_type))) < 0 ||
1704
+ (error = hash_header(ctx, size, type)) < 0)
1569
1705
  goto done;
1570
1706
 
1707
+ #ifdef GIT_EXPERIMENTAL_SHA256
1708
+ (*stream)->oid_type = db->options.oid_type;
1709
+ #endif
1571
1710
  (*stream)->hash_ctx = ctx;
1572
1711
  (*stream)->declared_size = size;
1573
1712
  (*stream)->received_bytes = 0;
@@ -1612,6 +1751,10 @@ int git_odb_stream_finalize_write(git_oid *out, git_odb_stream *stream)
1612
1751
 
1613
1752
  git_hash_final(out->id, stream->hash_ctx);
1614
1753
 
1754
+ #ifdef GIT_EXPERIMENTAL_SHA256
1755
+ out->type = stream->oid_type;
1756
+ #endif
1757
+
1615
1758
  if (git_odb__freshen(stream->backend->odb, out))
1616
1759
  return 0;
1617
1760
 
@@ -1786,10 +1929,11 @@ int git_odb_refresh(struct git_odb *db)
1786
1929
 
1787
1930
  int git_odb__error_mismatch(const git_oid *expected, const git_oid *actual)
1788
1931
  {
1789
- char expected_oid[GIT_OID_HEXSZ + 1], actual_oid[GIT_OID_HEXSZ + 1];
1932
+ char expected_oid[GIT_OID_MAX_HEXSIZE + 1],
1933
+ actual_oid[GIT_OID_MAX_HEXSIZE + 1];
1790
1934
 
1791
- git_oid_tostr(expected_oid, sizeof(expected_oid), expected);
1792
- git_oid_tostr(actual_oid, sizeof(actual_oid), actual);
1935
+ git_oid_tostr(expected_oid, git_oid_hexsize(git_oid_type(expected)) + 1, expected);
1936
+ git_oid_tostr(actual_oid, git_oid_hexsize(git_oid_type(actual)) + 1, actual);
1793
1937
 
1794
1938
  git_error_set(GIT_ERROR_ODB, "object hash mismatch - expected %s but got %s",
1795
1939
  expected_oid, actual_oid);
@@ -1801,7 +1945,7 @@ int git_odb__error_notfound(
1801
1945
  const char *message, const git_oid *oid, size_t oid_len)
1802
1946
  {
1803
1947
  if (oid != NULL) {
1804
- char oid_str[GIT_OID_HEXSZ + 1];
1948
+ char oid_str[GIT_OID_MAX_HEXSIZE + 1];
1805
1949
  git_oid_tostr(oid_str, oid_len+1, oid);
1806
1950
  git_error_set(GIT_ERROR_ODB, "object not found - %s (%.*s)",
1807
1951
  message, (int) oid_len, oid_str);
@@ -1819,7 +1963,7 @@ static int error_null_oid(int error, const char *message)
1819
1963
 
1820
1964
  int git_odb__error_ambiguous(const char *message)
1821
1965
  {
1822
- git_error_set(GIT_ERROR_ODB, "ambiguous SHA1 prefix - %s", message);
1966
+ git_error_set(GIT_ERROR_ODB, "ambiguous OID prefix - %s", message);
1823
1967
  return GIT_EAMBIGUOUS;
1824
1968
  }
1825
1969
 
@@ -10,6 +10,7 @@
10
10
  #include "common.h"
11
11
 
12
12
  #include "git2/odb.h"
13
+ #include "git2/odb_backend.h"
13
14
  #include "git2/oid.h"
14
15
  #include "git2/types.h"
15
16
  #include "git2/sys/commit_graph.h"
@@ -46,6 +47,7 @@ struct git_odb_object {
46
47
  struct git_odb {
47
48
  git_refcount rc;
48
49
  git_mutex lock; /* protects backends */
50
+ git_odb_options options;
49
51
  git_vector backends;
50
52
  git_cache own_cache;
51
53
  git_commit_graph *cgraph;
@@ -72,7 +74,7 @@ int git_odb__add_default_backends(
72
74
  * Hash a git_rawobj internally.
73
75
  * The `git_rawobj` is supposed to be previously initialized
74
76
  */
75
- int git_odb__hashobj(git_oid *id, git_rawobj *obj);
77
+ int git_odb__hashobj(git_oid *id, git_rawobj *obj, git_oid_t oid_type);
76
78
 
77
79
  /*
78
80
  * Format the object header such as it would appear in the on-disk object
@@ -89,14 +91,24 @@ int git_odb__format_object_header(size_t *out_len, char *hdr, size_t hdr_size, g
89
91
  * The fd is never closed, not even on error. It must be opened and closed
90
92
  * by the caller
91
93
  */
92
- int git_odb__hashfd(git_oid *out, git_file fd, size_t size, git_object_t type);
94
+ int git_odb__hashfd(
95
+ git_oid *out,
96
+ git_file fd,
97
+ size_t size,
98
+ git_object_t object_type,
99
+ git_oid_t oid_type);
93
100
 
94
101
  /*
95
102
  * Hash an open file descriptor applying an array of filters
96
103
  * Acts just like git_odb__hashfd with the addition of filters...
97
104
  */
98
105
  int git_odb__hashfd_filtered(
99
- git_oid *out, git_file fd, size_t len, git_object_t type, git_filter_list *fl);
106
+ git_oid *out,
107
+ git_file fd,
108
+ size_t len,
109
+ git_object_t object_type,
110
+ git_oid_t oid_type,
111
+ git_filter_list *fl);
100
112
 
101
113
  /*
102
114
  * Hash a `path`, assuming it could be a POSIX symlink: if the path is a
@@ -106,7 +118,7 @@ int git_odb__hashfd_filtered(
106
118
  * The hash type for this call is always `GIT_OBJECT_BLOB` because
107
119
  * symlinks may only point to blobs.
108
120
  */
109
- int git_odb__hashlink(git_oid *out, const char *path);
121
+ int git_odb__hashlink(git_oid *out, const char *path, git_oid_t oid_type);
110
122
 
111
123
  /**
112
124
  * Generate a GIT_EMISMATCH error for the ODB.
@@ -146,4 +158,31 @@ int git_odb__freshen(git_odb *db, const git_oid *id);
146
158
  /* fully free the object; internal method, DO NOT EXPORT */
147
159
  void git_odb_object__free(void *object);
148
160
 
161
+ /* SHA256 support */
162
+
163
+ int git_odb__new(git_odb **out, const git_odb_options *opts);
164
+
165
+ int git_odb__open(
166
+ git_odb **out,
167
+ const char *objects_dir,
168
+ const git_odb_options *opts);
169
+
170
+ int git_odb__hash(
171
+ git_oid *out,
172
+ const void *data,
173
+ size_t len,
174
+ git_object_t object_type,
175
+ git_oid_t oid_type);
176
+
177
+ int git_odb__hashfile(
178
+ git_oid *out,
179
+ const char *path,
180
+ git_object_t object_type,
181
+ git_oid_t oid_type);
182
+
183
+ GIT_EXTERN(int) git_odb__backend_loose(
184
+ git_odb_backend **out,
185
+ const char *objects_dir,
186
+ git_odb_backend_loose_options *opts);
187
+
149
188
  #endif