rugged 1.6.5 → 1.7.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (181) 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 +323 -120
  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/revwalk.c +26 -4
  114. data/vendor/libgit2/src/libgit2/stash.c +9 -8
  115. data/vendor/libgit2/src/libgit2/streams/mbedtls.c +0 -1
  116. data/vendor/libgit2/src/libgit2/streams/openssl.c +8 -16
  117. data/vendor/libgit2/src/libgit2/streams/schannel.c +715 -0
  118. data/vendor/libgit2/src/libgit2/streams/schannel.h +28 -0
  119. data/vendor/libgit2/src/libgit2/streams/socket.c +237 -51
  120. data/vendor/libgit2/src/libgit2/streams/socket.h +3 -1
  121. data/vendor/libgit2/src/libgit2/streams/stransport.c +40 -12
  122. data/vendor/libgit2/src/libgit2/streams/tls.c +5 -0
  123. data/vendor/libgit2/src/libgit2/submodule.h +3 -3
  124. data/vendor/libgit2/src/libgit2/threadstate.c +15 -2
  125. data/vendor/libgit2/src/libgit2/threadstate.h +1 -3
  126. data/vendor/libgit2/src/libgit2/transports/auth.h +1 -2
  127. data/vendor/libgit2/src/libgit2/transports/{auth_negotiate.c → auth_gssapi.c} +32 -32
  128. data/vendor/libgit2/src/libgit2/transports/auth_negotiate.h +1 -1
  129. data/vendor/libgit2/src/libgit2/transports/auth_ntlm.h +1 -1
  130. data/vendor/libgit2/src/libgit2/transports/{auth_ntlm.c → auth_ntlmclient.c} +12 -12
  131. data/vendor/libgit2/src/libgit2/transports/auth_sspi.c +341 -0
  132. data/vendor/libgit2/src/libgit2/transports/git.c +7 -8
  133. data/vendor/libgit2/src/libgit2/transports/http.c +7 -2
  134. data/vendor/libgit2/src/libgit2/transports/httpclient.c +5 -0
  135. data/vendor/libgit2/src/libgit2/transports/local.c +13 -4
  136. data/vendor/libgit2/src/libgit2/transports/smart.c +33 -27
  137. data/vendor/libgit2/src/libgit2/transports/smart.h +23 -8
  138. data/vendor/libgit2/src/libgit2/transports/smart_pkt.c +135 -15
  139. data/vendor/libgit2/src/libgit2/transports/smart_protocol.c +154 -47
  140. data/vendor/libgit2/src/libgit2/transports/ssh.c +3 -3
  141. data/vendor/libgit2/src/libgit2/transports/winhttp.c +14 -15
  142. data/vendor/libgit2/src/libgit2/tree-cache.c +26 -16
  143. data/vendor/libgit2/src/libgit2/tree-cache.h +5 -3
  144. data/vendor/libgit2/src/libgit2/tree.c +1 -1
  145. data/vendor/libgit2/src/libgit2/worktree.c +25 -10
  146. data/vendor/libgit2/src/util/alloc.c +65 -6
  147. data/vendor/libgit2/src/util/alloc.h +34 -9
  148. data/vendor/libgit2/src/util/allocators/failalloc.c +0 -60
  149. data/vendor/libgit2/src/util/allocators/failalloc.h +0 -6
  150. data/vendor/libgit2/src/util/allocators/stdalloc.c +2 -105
  151. data/vendor/libgit2/src/util/allocators/win32_leakcheck.c +0 -68
  152. data/vendor/libgit2/src/util/array.h +6 -1
  153. data/vendor/libgit2/src/util/cc-compat.h +2 -0
  154. data/vendor/libgit2/src/util/filebuf.c +6 -1
  155. data/vendor/libgit2/src/util/filebuf.h +19 -6
  156. data/vendor/libgit2/src/util/fs_path.c +1 -1
  157. data/vendor/libgit2/src/util/futils.c +8 -5
  158. data/vendor/libgit2/src/util/git2_features.h.in +9 -3
  159. data/vendor/libgit2/src/util/net.c +308 -157
  160. data/vendor/libgit2/src/util/net.h +25 -0
  161. data/vendor/libgit2/src/util/posix.c +54 -0
  162. data/vendor/libgit2/src/util/posix.h +22 -0
  163. data/vendor/libgit2/src/util/rand.c +6 -4
  164. data/vendor/libgit2/src/util/staticstr.h +66 -0
  165. data/vendor/libgit2/src/util/util.c +15 -10
  166. data/vendor/libgit2/src/util/util.h +24 -16
  167. data/vendor/libgit2/src/util/win32/error.c +1 -1
  168. data/vendor/libgit2/src/util/win32/path_w32.c +8 -8
  169. data/vendor/libgit2/src/util/win32/posix_w32.c +1 -1
  170. data/vendor/libgit2/src/util/win32/utf-conv.c +73 -75
  171. data/vendor/libgit2/src/util/win32/utf-conv.h +81 -14
  172. data/vendor/libgit2/src/util/win32/w32_util.c +1 -1
  173. metadata +28 -22
  174. data/vendor/libgit2/cmake/SelectWinHTTP.cmake +0 -17
  175. data/vendor/libgit2/src/libgit2/netops.c +0 -124
  176. data/vendor/libgit2/src/libgit2/netops.h +0 -68
  177. /data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xdiff.h +0 -0
  178. /data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xemit.h +0 -0
  179. /data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xinclude.h +0 -0
  180. /data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xprepare.h +0 -0
  181. /data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xtypes.h +0 -0
@@ -32,8 +32,6 @@ static int index_apply_to_wd_diff(git_index *index, int action, const git_strarr
32
32
  unsigned int flags,
33
33
  git_index_matched_path_cb cb, void *payload);
34
34
 
35
- #define minimal_entry_size (offsetof(struct entry_short, path))
36
-
37
35
  static const size_t INDEX_HEADER_SIZE = 12;
38
36
 
39
37
  static const unsigned int INDEX_VERSION_NUMBER_DEFAULT = 2;
@@ -65,7 +63,7 @@ struct entry_time {
65
63
  uint32_t nanoseconds;
66
64
  };
67
65
 
68
- struct entry_short {
66
+ struct entry_common {
69
67
  struct entry_time ctime;
70
68
  struct entry_time mtime;
71
69
  uint32_t dev;
@@ -74,25 +72,35 @@ struct entry_short {
74
72
  uint32_t uid;
75
73
  uint32_t gid;
76
74
  uint32_t file_size;
77
- unsigned char oid[GIT_OID_SHA1_SIZE];
78
- uint16_t flags;
79
- char path[1]; /* arbitrary length */
80
75
  };
81
76
 
82
- struct entry_long {
83
- struct entry_time ctime;
84
- struct entry_time mtime;
85
- uint32_t dev;
86
- uint32_t ino;
87
- uint32_t mode;
88
- uint32_t uid;
89
- uint32_t gid;
90
- uint32_t file_size;
91
- unsigned char oid[GIT_OID_SHA1_SIZE];
92
- uint16_t flags;
93
- uint16_t flags_extended;
94
- char path[1]; /* arbitrary length */
95
- };
77
+ #define entry_short(oid_size) \
78
+ struct { \
79
+ struct entry_common common; \
80
+ unsigned char oid[oid_size]; \
81
+ uint16_t flags; \
82
+ char path[1]; /* arbitrary length */ \
83
+ }
84
+
85
+ #define entry_long(oid_size) \
86
+ struct { \
87
+ struct entry_common common; \
88
+ unsigned char oid[oid_size]; \
89
+ uint16_t flags; \
90
+ uint16_t flags_extended; \
91
+ char path[1]; /* arbitrary length */ \
92
+ }
93
+
94
+ typedef entry_short(GIT_OID_SHA1_SIZE) index_entry_short_sha1;
95
+ typedef entry_long(GIT_OID_SHA1_SIZE) index_entry_long_sha1;
96
+
97
+ #ifdef GIT_EXPERIMENTAL_SHA256
98
+ typedef entry_short(GIT_OID_SHA256_SIZE) index_entry_short_sha256;
99
+ typedef entry_long(GIT_OID_SHA256_SIZE) index_entry_long_sha256;
100
+ #endif
101
+
102
+ #undef entry_short
103
+ #undef entry_long
96
104
 
97
105
  struct entry_srch_key {
98
106
  const char *path;
@@ -115,12 +123,12 @@ struct reuc_entry_internal {
115
123
  bool git_index__enforce_unsaved_safety = false;
116
124
 
117
125
  /* local declarations */
118
- static int read_extension(size_t *read_len, git_index *index, const char *buffer, size_t buffer_size);
126
+ static int read_extension(size_t *read_len, git_index *index, size_t checksum_size, const char *buffer, size_t buffer_size);
119
127
  static int read_header(struct index_header *dest, const void *buffer);
120
128
 
121
129
  static int parse_index(git_index *index, const char *buffer, size_t buffer_size);
122
130
  static bool is_index_extended(git_index *index);
123
- static int write_index(unsigned char checksum[GIT_HASH_SHA1_SIZE], size_t *checksum_size, git_index *index, git_filebuf *file);
131
+ static int write_index(unsigned char checksum[GIT_HASH_MAX_SIZE], size_t *checksum_size, git_index *index, git_filebuf *file);
124
132
 
125
133
  static void index_entry_free(git_index_entry *entry);
126
134
  static void index_entry_reuc_free(git_index_reuc_entry *reuc);
@@ -401,7 +409,10 @@ void git_index__set_ignore_case(git_index *index, bool ignore_case)
401
409
  git_vector_sort(&index->reuc);
402
410
  }
403
411
 
404
- int git_index_open(git_index **index_out, const char *index_path)
412
+ int git_index__open(
413
+ git_index **index_out,
414
+ const char *index_path,
415
+ git_oid_t oid_type)
405
416
  {
406
417
  git_index *index;
407
418
  int error = -1;
@@ -411,6 +422,8 @@ int git_index_open(git_index **index_out, const char *index_path)
411
422
  index = git__calloc(1, sizeof(git_index));
412
423
  GIT_ERROR_CHECK_ALLOC(index);
413
424
 
425
+ index->oid_type = oid_type;
426
+
414
427
  if (git_pool_init(&index->tree_pool, 1) < 0)
415
428
  goto fail;
416
429
 
@@ -451,10 +464,34 @@ fail:
451
464
  return error;
452
465
  }
453
466
 
467
+ #ifdef GIT_EXPERIMENTAL_SHA256
468
+ int git_index_open(git_index **index_out, const char *index_path, git_oid_t oid_type)
469
+ {
470
+ return git_index__open(index_out, index_path, oid_type);
471
+ }
472
+ #else
473
+ int git_index_open(git_index **index_out, const char *index_path)
474
+ {
475
+ return git_index__open(index_out, index_path, GIT_OID_SHA1);
476
+ }
477
+ #endif
478
+
479
+ int git_index__new(git_index **out, git_oid_t oid_type)
480
+ {
481
+ return git_index__open(out, NULL, oid_type);
482
+ }
483
+
484
+ #ifdef GIT_EXPERIMENTAL_SHA256
485
+ int git_index_new(git_index **out, git_oid_t oid_type)
486
+ {
487
+ return git_index__new(out, oid_type);
488
+ }
489
+ #else
454
490
  int git_index_new(git_index **out)
455
491
  {
456
- return git_index_open(out, NULL);
492
+ return git_index__new(out, GIT_OID_SHA1);
457
493
  }
494
+ #endif
458
495
 
459
496
  static void index_free(git_index *index)
460
497
  {
@@ -620,8 +657,8 @@ static int compare_checksum(git_index *index)
620
657
  {
621
658
  int fd;
622
659
  ssize_t bytes_read;
623
- unsigned char checksum[GIT_HASH_SHA1_SIZE];
624
- size_t checksum_size = GIT_HASH_SHA1_SIZE;
660
+ unsigned char checksum[GIT_HASH_MAX_SIZE];
661
+ size_t checksum_size = git_oid_size(index->oid_type);
625
662
 
626
663
  if ((fd = p_open(index->index_file_path, O_RDONLY)) < 0)
627
664
  return fd;
@@ -2309,6 +2346,7 @@ static int index_error_invalid(const char *message)
2309
2346
  static int read_reuc(git_index *index, const char *buffer, size_t size)
2310
2347
  {
2311
2348
  const char *endptr;
2349
+ size_t oid_size = git_oid_size(index->oid_type);
2312
2350
  size_t len;
2313
2351
  int i;
2314
2352
 
@@ -2357,16 +2395,16 @@ static int read_reuc(git_index *index, const char *buffer, size_t size)
2357
2395
  for (i = 0; i < 3; i++) {
2358
2396
  if (!lost->mode[i])
2359
2397
  continue;
2360
- if (size < GIT_OID_SHA1_SIZE) {
2398
+ if (size < oid_size) {
2361
2399
  index_entry_reuc_free(lost);
2362
2400
  return index_error_invalid("reading reuc entry oid");
2363
2401
  }
2364
2402
 
2365
- if (git_oid__fromraw(&lost->oid[i], (const unsigned char *) buffer, GIT_OID_SHA1) < 0)
2403
+ if (git_oid__fromraw(&lost->oid[i], (const unsigned char *) buffer, index->oid_type) < 0)
2366
2404
  return -1;
2367
2405
 
2368
- size -= GIT_OID_SHA1_SIZE;
2369
- buffer += GIT_OID_SHA1_SIZE;
2406
+ size -= oid_size;
2407
+ buffer += oid_size;
2370
2408
  }
2371
2409
 
2372
2410
  /* entry was read successfully - insert into reuc vector */
@@ -2436,73 +2474,157 @@ out_err:
2436
2474
  return 0;
2437
2475
  }
2438
2476
 
2439
- static size_t index_entry_size(size_t path_len, size_t varint_len, uint32_t flags)
2477
+ GIT_INLINE(size_t) index_entry_path_offset(
2478
+ git_oid_t oid_type,
2479
+ uint32_t flags)
2480
+ {
2481
+ if (oid_type == GIT_OID_SHA1)
2482
+ return (flags & GIT_INDEX_ENTRY_EXTENDED) ?
2483
+ offsetof(index_entry_long_sha1, path) :
2484
+ offsetof(index_entry_short_sha1, path);
2485
+
2486
+ #ifdef GIT_EXPERIMENTAL_SHA256
2487
+ else if (oid_type == GIT_OID_SHA256)
2488
+ return (flags & GIT_INDEX_ENTRY_EXTENDED) ?
2489
+ offsetof(index_entry_long_sha256, path) :
2490
+ offsetof(index_entry_short_sha256, path);
2491
+ #endif
2492
+
2493
+ git_error_set(GIT_ERROR_INTERNAL, "invalid oid type");
2494
+ return 0;
2495
+ }
2496
+
2497
+ GIT_INLINE(size_t) index_entry_flags_offset(git_oid_t oid_type)
2440
2498
  {
2499
+ if (oid_type == GIT_OID_SHA1)
2500
+ return offsetof(index_entry_long_sha1, flags_extended);
2501
+
2502
+ #ifdef GIT_EXPERIMENTAL_SHA256
2503
+ else if (oid_type == GIT_OID_SHA256)
2504
+ return offsetof(index_entry_long_sha256, flags_extended);
2505
+ #endif
2506
+
2507
+ git_error_set(GIT_ERROR_INTERNAL, "invalid oid type");
2508
+ return 0;
2509
+ }
2510
+
2511
+ static size_t index_entry_size(
2512
+ size_t path_len,
2513
+ size_t varint_len,
2514
+ git_oid_t oid_type,
2515
+ uint32_t flags)
2516
+ {
2517
+ size_t offset, size;
2518
+
2519
+ if (!(offset = index_entry_path_offset(oid_type, flags)))
2520
+ return 0;
2521
+
2441
2522
  if (varint_len) {
2442
- if (flags & GIT_INDEX_ENTRY_EXTENDED)
2443
- return offsetof(struct entry_long, path) + path_len + 1 + varint_len;
2444
- else
2445
- return offsetof(struct entry_short, path) + path_len + 1 + varint_len;
2523
+ if (GIT_ADD_SIZET_OVERFLOW(&size, offset, path_len) ||
2524
+ GIT_ADD_SIZET_OVERFLOW(&size, size, 1) ||
2525
+ GIT_ADD_SIZET_OVERFLOW(&size, size, varint_len))
2526
+ return 0;
2446
2527
  } else {
2447
- #define entry_size(type,len) ((offsetof(type, path) + (len) + 8) & ~7)
2448
- if (flags & GIT_INDEX_ENTRY_EXTENDED)
2449
- return entry_size(struct entry_long, path_len);
2450
- else
2451
- return entry_size(struct entry_short, path_len);
2452
- #undef entry_size
2528
+ if (GIT_ADD_SIZET_OVERFLOW(&size, offset, path_len) ||
2529
+ GIT_ADD_SIZET_OVERFLOW(&size, size, 8))
2530
+ return 0;
2531
+
2532
+ size &= ~7;
2453
2533
  }
2534
+
2535
+ return size;
2454
2536
  }
2455
2537
 
2456
2538
  static int read_entry(
2457
2539
  git_index_entry **out,
2458
2540
  size_t *out_size,
2459
2541
  git_index *index,
2542
+ size_t checksum_size,
2460
2543
  const void *buffer,
2461
2544
  size_t buffer_size,
2462
2545
  const char *last)
2463
2546
  {
2464
- size_t path_length, entry_size;
2547
+ size_t path_length, path_offset, entry_size;
2465
2548
  const char *path_ptr;
2466
- struct entry_short source;
2549
+ struct entry_common *source_common;
2550
+ index_entry_short_sha1 source_sha1;
2551
+ #ifdef GIT_EXPERIMENTAL_SHA256
2552
+ index_entry_short_sha256 source_sha256;
2553
+ #endif
2467
2554
  git_index_entry entry = {{0}};
2468
2555
  bool compressed = index->version >= INDEX_VERSION_NUMBER_COMP;
2469
2556
  char *tmp_path = NULL;
2470
- size_t checksum_size = GIT_HASH_SHA1_SIZE;
2557
+
2558
+ size_t minimal_entry_size = index_entry_path_offset(index->oid_type, 0);
2471
2559
 
2472
2560
  if (checksum_size + minimal_entry_size > buffer_size)
2473
2561
  return -1;
2474
2562
 
2475
2563
  /* buffer is not guaranteed to be aligned */
2476
- memcpy(&source, buffer, sizeof(struct entry_short));
2477
-
2478
- entry.ctime.seconds = (git_time_t)ntohl(source.ctime.seconds);
2479
- entry.ctime.nanoseconds = ntohl(source.ctime.nanoseconds);
2480
- entry.mtime.seconds = (git_time_t)ntohl(source.mtime.seconds);
2481
- entry.mtime.nanoseconds = ntohl(source.mtime.nanoseconds);
2482
- entry.dev = ntohl(source.dev);
2483
- entry.ino = ntohl(source.ino);
2484
- entry.mode = ntohl(source.mode);
2485
- entry.uid = ntohl(source.uid);
2486
- entry.gid = ntohl(source.gid);
2487
- entry.file_size = ntohl(source.file_size);
2488
- entry.flags = ntohs(source.flags);
2489
-
2490
- if (git_oid__fromraw(&entry.id, source.oid, GIT_OID_SHA1) < 0)
2564
+ switch (index->oid_type) {
2565
+ case GIT_OID_SHA1:
2566
+ source_common = &source_sha1.common;
2567
+ memcpy(&source_sha1, buffer, sizeof(source_sha1));
2568
+ break;
2569
+ #ifdef GIT_EXPERIMENTAL_SHA256
2570
+ case GIT_OID_SHA256:
2571
+ source_common = &source_sha256.common;
2572
+ memcpy(&source_sha256, buffer, sizeof(source_sha256));
2573
+ break;
2574
+ #endif
2575
+ default:
2576
+ GIT_ASSERT(!"invalid oid type");
2577
+ }
2578
+
2579
+ entry.ctime.seconds = (git_time_t)ntohl(source_common->ctime.seconds);
2580
+ entry.ctime.nanoseconds = ntohl(source_common->ctime.nanoseconds);
2581
+ entry.mtime.seconds = (git_time_t)ntohl(source_common->mtime.seconds);
2582
+ entry.mtime.nanoseconds = ntohl(source_common->mtime.nanoseconds);
2583
+ entry.dev = ntohl(source_common->dev);
2584
+ entry.ino = ntohl(source_common->ino);
2585
+ entry.mode = ntohl(source_common->mode);
2586
+ entry.uid = ntohl(source_common->uid);
2587
+ entry.gid = ntohl(source_common->gid);
2588
+ entry.file_size = ntohl(source_common->file_size);
2589
+
2590
+ switch (index->oid_type) {
2591
+ case GIT_OID_SHA1:
2592
+ if (git_oid__fromraw(&entry.id, source_sha1.oid,
2593
+ GIT_OID_SHA1) < 0)
2594
+ return -1;
2595
+ entry.flags = ntohs(source_sha1.flags);
2596
+ break;
2597
+ #ifdef GIT_EXPERIMENTAL_SHA256
2598
+ case GIT_OID_SHA256:
2599
+ if (git_oid__fromraw(&entry.id, source_sha256.oid,
2600
+ GIT_OID_SHA256) < 0)
2601
+ return -1;
2602
+ entry.flags = ntohs(source_sha256.flags);
2603
+ break;
2604
+ #endif
2605
+ default:
2606
+ GIT_ASSERT(!"invalid oid type");
2607
+ }
2608
+
2609
+ if (!(path_offset = index_entry_path_offset(index->oid_type, entry.flags)))
2491
2610
  return -1;
2492
2611
 
2612
+
2493
2613
  if (entry.flags & GIT_INDEX_ENTRY_EXTENDED) {
2494
2614
  uint16_t flags_raw;
2495
2615
  size_t flags_offset;
2496
2616
 
2497
- flags_offset = offsetof(struct entry_long, flags_extended);
2498
- memcpy(&flags_raw, (const char *) buffer + flags_offset,
2499
- sizeof(flags_raw));
2617
+ if (!(flags_offset = index_entry_flags_offset(index->oid_type)))
2618
+ return -1;
2619
+
2620
+ memcpy(&flags_raw, (const char *)buffer + flags_offset, sizeof(flags_raw));
2500
2621
  flags_raw = ntohs(flags_raw);
2501
2622
 
2502
2623
  memcpy(&entry.flags_extended, &flags_raw, sizeof(flags_raw));
2503
- path_ptr = (const char *) buffer + offsetof(struct entry_long, path);
2504
- } else
2505
- path_ptr = (const char *) buffer + offsetof(struct entry_short, path);
2624
+ path_ptr = (const char *)buffer + path_offset;
2625
+ } else {
2626
+ path_ptr = (const char *)buffer + path_offset;
2627
+ }
2506
2628
 
2507
2629
  if (!compressed) {
2508
2630
  path_length = entry.flags & GIT_INDEX_ENTRY_NAMEMASK;
@@ -2514,12 +2636,12 @@ static int read_entry(
2514
2636
 
2515
2637
  path_end = memchr(path_ptr, '\0', buffer_size);
2516
2638
  if (path_end == NULL)
2517
- return -1;
2639
+ return index_error_invalid("invalid path name");
2518
2640
 
2519
2641
  path_length = path_end - path_ptr;
2520
2642
  }
2521
2643
 
2522
- entry_size = index_entry_size(path_length, 0, entry.flags);
2644
+ entry_size = index_entry_size(path_length, 0, index->oid_type, entry.flags);
2523
2645
  entry.path = (char *)path_ptr;
2524
2646
  } else {
2525
2647
  size_t varint_len, last_len, prefix_len, suffix_len, path_len;
@@ -2545,15 +2667,18 @@ static int read_entry(
2545
2667
 
2546
2668
  memcpy(tmp_path, last, prefix_len);
2547
2669
  memcpy(tmp_path + prefix_len, path_ptr + varint_len, suffix_len + 1);
2548
- entry_size = index_entry_size(suffix_len, varint_len, entry.flags);
2670
+
2671
+ entry_size = index_entry_size(suffix_len, varint_len, index->oid_type, entry.flags);
2549
2672
  entry.path = tmp_path;
2550
2673
  }
2551
2674
 
2552
2675
  if (entry_size == 0)
2553
2676
  return -1;
2554
2677
 
2555
- if (checksum_size + entry_size > buffer_size)
2678
+ if (checksum_size + entry_size > buffer_size) {
2679
+ git_error_set(GIT_ERROR_INTERNAL, "invalid index checksum");
2556
2680
  return -1;
2681
+ }
2557
2682
 
2558
2683
  if (index_entry_dup(out, index, &entry) < 0) {
2559
2684
  git__free(tmp_path);
@@ -2582,11 +2707,10 @@ static int read_header(struct index_header *dest, const void *buffer)
2582
2707
  return 0;
2583
2708
  }
2584
2709
 
2585
- static int read_extension(size_t *read_len, git_index *index, const char *buffer, size_t buffer_size)
2710
+ static int read_extension(size_t *read_len, git_index *index, size_t checksum_size, const char *buffer, size_t buffer_size)
2586
2711
  {
2587
2712
  struct index_extension dest;
2588
2713
  size_t total_size;
2589
- size_t checksum_size = GIT_HASH_SHA1_SIZE;
2590
2714
 
2591
2715
  /* buffer is not guaranteed to be aligned */
2592
2716
  memcpy(&dest, buffer, sizeof(struct index_extension));
@@ -2605,7 +2729,7 @@ static int read_extension(size_t *read_len, git_index *index, const char *buffer
2605
2729
  if (dest.signature[0] >= 'A' && dest.signature[0] <= 'Z') {
2606
2730
  /* tree cache */
2607
2731
  if (memcmp(dest.signature, INDEX_EXT_TREECACHE_SIG, 4) == 0) {
2608
- if (git_tree_cache_read(&index->tree, buffer + 8, dest.extension_size, &index->tree_pool) < 0)
2732
+ if (git_tree_cache_read(&index->tree, buffer + 8, dest.extension_size, index->oid_type, &index->tree_pool) < 0)
2609
2733
  return -1;
2610
2734
  } else if (memcmp(dest.signature, INDEX_EXT_UNMERGED_SIG, 4) == 0) {
2611
2735
  if (read_reuc(index, buffer + 8, dest.extension_size) < 0)
@@ -2633,8 +2757,8 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size)
2633
2757
  int error = 0;
2634
2758
  unsigned int i;
2635
2759
  struct index_header header = { 0 };
2636
- unsigned char checksum[GIT_HASH_SHA1_SIZE];
2637
- size_t checksum_size = GIT_HASH_SHA1_SIZE;
2760
+ unsigned char checksum[GIT_HASH_MAX_SIZE];
2761
+ size_t checksum_size = git_hash_size(git_oid_algorithm(index->oid_type));
2638
2762
  const char *last = NULL;
2639
2763
  const char *empty = "";
2640
2764
 
@@ -2649,9 +2773,12 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size)
2649
2773
  if (buffer_size < INDEX_HEADER_SIZE + checksum_size)
2650
2774
  return index_error_invalid("insufficient buffer space");
2651
2775
 
2652
- /* Precalculate the SHA1 of the files's contents -- we'll match it to
2653
- * the provided SHA1 in the footer */
2654
- git_hash_buf(checksum, buffer, buffer_size - checksum_size, GIT_HASH_ALGORITHM_SHA1);
2776
+ /*
2777
+ * Precalculate the hash of the files's contents -- we'll match
2778
+ * it to the provided checksum in the footer.
2779
+ */
2780
+ git_hash_buf(checksum, buffer, buffer_size - checksum_size,
2781
+ git_oid_algorithm(index->oid_type));
2655
2782
 
2656
2783
  /* Parse header */
2657
2784
  if ((error = read_header(&header, buffer)) < 0)
@@ -2673,7 +2800,7 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size)
2673
2800
  git_index_entry *entry = NULL;
2674
2801
  size_t entry_size;
2675
2802
 
2676
- if ((error = read_entry(&entry, &entry_size, index, buffer, buffer_size, last)) < 0) {
2803
+ if ((error = read_entry(&entry, &entry_size, index, checksum_size, buffer, buffer_size, last)) < 0) {
2677
2804
  error = index_error_invalid("invalid entry");
2678
2805
  goto done;
2679
2806
  }
@@ -2704,7 +2831,7 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size)
2704
2831
  while (buffer_size > checksum_size) {
2705
2832
  size_t extension_size;
2706
2833
 
2707
- if ((error = read_extension(&extension_size, index, buffer, buffer_size)) < 0) {
2834
+ if ((error = read_extension(&extension_size, index, checksum_size, buffer, buffer_size)) < 0) {
2708
2835
  goto done;
2709
2836
  }
2710
2837
 
@@ -2717,7 +2844,10 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size)
2717
2844
  goto done;
2718
2845
  }
2719
2846
 
2720
- /* 160-bit SHA-1 over the content of the index file before this checksum. */
2847
+ /*
2848
+ * SHA-1 or SHA-256 (depending on the repository's object format)
2849
+ * over the content of the index file before this checksum.
2850
+ */
2721
2851
  if (memcmp(checksum, buffer, checksum_size) != 0) {
2722
2852
  error = index_error_invalid(
2723
2853
  "calculated checksum does not match expected");
@@ -2757,16 +2887,40 @@ static bool is_index_extended(git_index *index)
2757
2887
  return (extended > 0);
2758
2888
  }
2759
2889
 
2760
- static int write_disk_entry(git_filebuf *file, git_index_entry *entry, const char *last)
2890
+ static int write_disk_entry(
2891
+ git_index *index,
2892
+ git_filebuf *file,
2893
+ git_index_entry *entry,
2894
+ const char *last)
2761
2895
  {
2762
2896
  void *mem = NULL;
2763
- struct entry_short ondisk;
2764
- size_t path_len, disk_size;
2897
+ struct entry_common *ondisk_common;
2898
+ size_t path_len, path_offset, disk_size;
2765
2899
  int varint_len = 0;
2766
2900
  char *path;
2767
2901
  const char *path_start = entry->path;
2768
2902
  size_t same_len = 0;
2769
2903
 
2904
+ index_entry_short_sha1 ondisk_sha1;
2905
+ index_entry_long_sha1 ondisk_ext_sha1;
2906
+ #ifdef GIT_EXPERIMENTAL_SHA256
2907
+ index_entry_short_sha256 ondisk_sha256;
2908
+ index_entry_long_sha256 ondisk_ext_sha256;
2909
+ #endif
2910
+
2911
+ switch (index->oid_type) {
2912
+ case GIT_OID_SHA1:
2913
+ ondisk_common = &ondisk_sha1.common;
2914
+ break;
2915
+ #ifdef GIT_EXPERIMENTAL_SHA256
2916
+ case GIT_OID_SHA256:
2917
+ ondisk_common = &ondisk_sha256.common;
2918
+ break;
2919
+ #endif
2920
+ default:
2921
+ GIT_ASSERT(!"invalid oid type");
2922
+ }
2923
+
2770
2924
  path_len = ((struct entry_internal *)entry)->pathlen;
2771
2925
 
2772
2926
  if (last) {
@@ -2783,9 +2937,9 @@ static int write_disk_entry(git_filebuf *file, git_index_entry *entry, const cha
2783
2937
  varint_len = git_encode_varint(NULL, 0, strlen(last) - same_len);
2784
2938
  }
2785
2939
 
2786
- disk_size = index_entry_size(path_len, varint_len, entry->flags);
2940
+ disk_size = index_entry_size(path_len, varint_len, index->oid_type, entry->flags);
2787
2941
 
2788
- if (git_filebuf_reserve(file, &mem, disk_size) < 0)
2942
+ if (!disk_size || git_filebuf_reserve(file, &mem, disk_size) < 0)
2789
2943
  return -1;
2790
2944
 
2791
2945
  memset(mem, 0x0, disk_size);
@@ -2800,35 +2954,77 @@ static int write_disk_entry(git_filebuf *file, git_index_entry *entry, const cha
2800
2954
  *
2801
2955
  * In 2038 I will be either too dead or too rich to care about this
2802
2956
  */
2803
- ondisk.ctime.seconds = htonl((uint32_t)entry->ctime.seconds);
2804
- ondisk.mtime.seconds = htonl((uint32_t)entry->mtime.seconds);
2805
- ondisk.ctime.nanoseconds = htonl(entry->ctime.nanoseconds);
2806
- ondisk.mtime.nanoseconds = htonl(entry->mtime.nanoseconds);
2807
- ondisk.dev = htonl(entry->dev);
2808
- ondisk.ino = htonl(entry->ino);
2809
- ondisk.mode = htonl(entry->mode);
2810
- ondisk.uid = htonl(entry->uid);
2811
- ondisk.gid = htonl(entry->gid);
2812
- ondisk.file_size = htonl((uint32_t)entry->file_size);
2813
- git_oid_raw_cpy(ondisk.oid, entry->id.id, GIT_OID_SHA1_SIZE);
2814
- ondisk.flags = htons(entry->flags);
2957
+ ondisk_common->ctime.seconds = htonl((uint32_t)entry->ctime.seconds);
2958
+ ondisk_common->mtime.seconds = htonl((uint32_t)entry->mtime.seconds);
2959
+ ondisk_common->ctime.nanoseconds = htonl(entry->ctime.nanoseconds);
2960
+ ondisk_common->mtime.nanoseconds = htonl(entry->mtime.nanoseconds);
2961
+ ondisk_common->dev = htonl(entry->dev);
2962
+ ondisk_common->ino = htonl(entry->ino);
2963
+ ondisk_common->mode = htonl(entry->mode);
2964
+ ondisk_common->uid = htonl(entry->uid);
2965
+ ondisk_common->gid = htonl(entry->gid);
2966
+ ondisk_common->file_size = htonl((uint32_t)entry->file_size);
2967
+
2968
+ switch (index->oid_type) {
2969
+ case GIT_OID_SHA1:
2970
+ git_oid_raw_cpy(ondisk_sha1.oid, entry->id.id, GIT_OID_SHA1_SIZE);
2971
+ ondisk_sha1.flags = htons(entry->flags);
2972
+ break;
2973
+ #ifdef GIT_EXPERIMENTAL_SHA256
2974
+ case GIT_OID_SHA256:
2975
+ git_oid_raw_cpy(ondisk_sha256.oid, entry->id.id, GIT_OID_SHA256_SIZE);
2976
+ ondisk_sha256.flags = htons(entry->flags);
2977
+ break;
2978
+ #endif
2979
+ default:
2980
+ GIT_ASSERT(!"invalid oid type");
2981
+ }
2982
+
2983
+ path_offset = index_entry_path_offset(index->oid_type, entry->flags);
2815
2984
 
2816
2985
  if (entry->flags & GIT_INDEX_ENTRY_EXTENDED) {
2817
- const size_t path_offset = offsetof(struct entry_long, path);
2818
- struct entry_long ondisk_ext;
2819
- memcpy(&ondisk_ext, &ondisk, sizeof(struct entry_short));
2820
- ondisk_ext.flags_extended = htons(entry->flags_extended &
2986
+ struct entry_common *ondisk_ext;
2987
+ uint16_t flags_extended = htons(entry->flags_extended &
2821
2988
  GIT_INDEX_ENTRY_EXTENDED_FLAGS);
2822
- memcpy(mem, &ondisk_ext, path_offset);
2823
- path = (char *)mem + path_offset;
2824
- disk_size -= path_offset;
2989
+
2990
+ switch (index->oid_type) {
2991
+ case GIT_OID_SHA1:
2992
+ memcpy(&ondisk_ext_sha1, &ondisk_sha1,
2993
+ sizeof(index_entry_short_sha1));
2994
+ ondisk_ext_sha1.flags_extended = flags_extended;
2995
+ ondisk_ext = &ondisk_ext_sha1.common;
2996
+ break;
2997
+ #ifdef GIT_EXPERIMENTAL_SHA256
2998
+ case GIT_OID_SHA256:
2999
+ memcpy(&ondisk_ext_sha256, &ondisk_sha256,
3000
+ sizeof(index_entry_short_sha256));
3001
+ ondisk_ext_sha256.flags_extended = flags_extended;
3002
+ ondisk_ext = &ondisk_ext_sha256.common;
3003
+ break;
3004
+ #endif
3005
+ default:
3006
+ GIT_ASSERT(!"invalid oid type");
3007
+ }
3008
+
3009
+ memcpy(mem, ondisk_ext, path_offset);
2825
3010
  } else {
2826
- const size_t path_offset = offsetof(struct entry_short, path);
2827
- memcpy(mem, &ondisk, path_offset);
2828
- path = (char *)mem + path_offset;
2829
- disk_size -= path_offset;
3011
+ switch (index->oid_type) {
3012
+ case GIT_OID_SHA1:
3013
+ memcpy(mem, &ondisk_sha1, path_offset);
3014
+ break;
3015
+ #ifdef GIT_EXPERIMENTAL_SHA256
3016
+ case GIT_OID_SHA256:
3017
+ memcpy(mem, &ondisk_sha256, path_offset);
3018
+ break;
3019
+ #endif
3020
+ default:
3021
+ GIT_ASSERT(!"invalid oid type");
3022
+ }
2830
3023
  }
2831
3024
 
3025
+ path = (char *)mem + path_offset;
3026
+ disk_size -= path_offset;
3027
+
2832
3028
  if (last) {
2833
3029
  varint_len = git_encode_varint((unsigned char *) path,
2834
3030
  disk_size, strlen(last) - same_len);
@@ -2880,7 +3076,7 @@ static int write_entries(git_index *index, git_filebuf *file)
2880
3076
  last = "";
2881
3077
 
2882
3078
  git_vector_foreach(entries, i, entry) {
2883
- if ((error = write_disk_entry(file, entry, last)) < 0)
3079
+ if ((error = write_disk_entry(index, file, entry, last)) < 0)
2884
3080
  break;
2885
3081
  if (index->version >= INDEX_VERSION_NUMBER_COMP)
2886
3082
  last = entry->path;
@@ -2958,8 +3154,9 @@ done:
2958
3154
  return error;
2959
3155
  }
2960
3156
 
2961
- static int create_reuc_extension_data(git_str *reuc_buf, git_index_reuc_entry *reuc)
3157
+ static int create_reuc_extension_data(git_str *reuc_buf, git_index *index, git_index_reuc_entry *reuc)
2962
3158
  {
3159
+ size_t oid_size = git_oid_size(index->oid_type);
2963
3160
  int i;
2964
3161
  int error = 0;
2965
3162
 
@@ -2973,7 +3170,7 @@ static int create_reuc_extension_data(git_str *reuc_buf, git_index_reuc_entry *r
2973
3170
  }
2974
3171
 
2975
3172
  for (i = 0; i < 3; i++) {
2976
- if (reuc->mode[i] && (error = git_str_put(reuc_buf, (char *)&reuc->oid[i].id, GIT_OID_SHA1_SIZE)) < 0)
3173
+ if (reuc->mode[i] && (error = git_str_put(reuc_buf, (char *)&reuc->oid[i].id, oid_size)) < 0)
2977
3174
  return error;
2978
3175
  }
2979
3176
 
@@ -2990,7 +3187,7 @@ static int write_reuc_extension(git_index *index, git_filebuf *file)
2990
3187
  int error = 0;
2991
3188
 
2992
3189
  git_vector_foreach(out, i, reuc) {
2993
- if ((error = create_reuc_extension_data(&reuc_buf, reuc)) < 0)
3190
+ if ((error = create_reuc_extension_data(&reuc_buf, index, reuc)) < 0)
2994
3191
  goto done;
2995
3192
  }
2996
3193
 
@@ -3039,7 +3236,7 @@ static void clear_uptodate(git_index *index)
3039
3236
  }
3040
3237
 
3041
3238
  static int write_index(
3042
- unsigned char checksum[GIT_HASH_SHA1_SIZE],
3239
+ unsigned char checksum[GIT_HASH_MAX_SIZE],
3043
3240
  size_t *checksum_size,
3044
3241
  git_index *index,
3045
3242
  git_filebuf *file)
@@ -3051,7 +3248,9 @@ static int write_index(
3051
3248
  GIT_ASSERT_ARG(index);
3052
3249
  GIT_ASSERT_ARG(file);
3053
3250
 
3054
- *checksum_size = GIT_HASH_SHA1_SIZE;
3251
+ GIT_ASSERT(index->oid_type);
3252
+
3253
+ *checksum_size = git_hash_size(git_oid_algorithm(index->oid_type));
3055
3254
 
3056
3255
  if (index->version <= INDEX_VERSION_NUMBER_EXT) {
3057
3256
  is_extended = is_index_extended(index);
@@ -3212,7 +3411,7 @@ cleanup:
3212
3411
  if (error < 0)
3213
3412
  return error;
3214
3413
 
3215
- error = git_tree_cache_read_tree(&index->tree, tree, &index->tree_pool);
3414
+ error = git_tree_cache_read_tree(&index->tree, tree, index->oid_type, &index->tree_pool);
3216
3415
 
3217
3416
  return error;
3218
3417
  }
@@ -3671,19 +3870,23 @@ int git_indexwriter_init(
3671
3870
  git_indexwriter *writer,
3672
3871
  git_index *index)
3673
3872
  {
3674
- int error;
3873
+ int filebuf_hash, error;
3675
3874
 
3676
3875
  GIT_REFCOUNT_INC(index);
3677
3876
 
3678
3877
  writer->index = index;
3679
3878
 
3879
+ filebuf_hash = git_filebuf_hash_flags(git_oid_algorithm(index->oid_type));
3880
+ GIT_ASSERT(filebuf_hash);
3881
+
3680
3882
  if (!index->index_file_path)
3681
3883
  return create_index_error(-1,
3682
3884
  "failed to write index: The index is in-memory only");
3683
3885
 
3684
- if ((error = git_filebuf_open(
3685
- &writer->file, index->index_file_path, GIT_FILEBUF_HASH_CONTENTS, GIT_INDEX_FILE_MODE)) < 0) {
3686
-
3886
+ if ((error = git_filebuf_open(&writer->file,
3887
+ index->index_file_path,
3888
+ git_filebuf_hash_flags(filebuf_hash),
3889
+ GIT_INDEX_FILE_MODE)) < 0) {
3687
3890
  if (error == GIT_ELOCKED)
3688
3891
  git_error_set(GIT_ERROR_INDEX, "the index is locked; this might be due to a concurrent or crashed process");
3689
3892
 
@@ -3715,7 +3918,7 @@ int git_indexwriter_init_for_operation(
3715
3918
 
3716
3919
  int git_indexwriter_commit(git_indexwriter *writer)
3717
3920
  {
3718
- unsigned char checksum[GIT_HASH_SHA1_SIZE];
3921
+ unsigned char checksum[GIT_HASH_MAX_SIZE];
3719
3922
  size_t checksum_size;
3720
3923
  int error;
3721
3924