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
@@ -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