rugged 1.6.3 → 1.7.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (182) hide show
  1. checksums.yaml +4 -4
  2. data/ext/rugged/rugged_allocator.c +0 -54
  3. data/lib/rugged/version.rb +1 -1
  4. data/vendor/libgit2/CMakeLists.txt +3 -8
  5. data/vendor/libgit2/cmake/CheckPrototypeDefinitionSafe.cmake +16 -0
  6. data/vendor/libgit2/cmake/SelectGSSAPI.cmake +3 -3
  7. data/vendor/libgit2/cmake/SelectHTTPSBackend.cmake +21 -2
  8. data/vendor/libgit2/cmake/SelectHashes.cmake +4 -0
  9. data/vendor/libgit2/cmake/SelectXdiff.cmake +9 -0
  10. data/vendor/libgit2/deps/pcre/LICENCE +5 -5
  11. data/vendor/libgit2/deps/pcre/pcre.h +2 -2
  12. data/vendor/libgit2/deps/pcre/pcre_compile.c +6 -3
  13. data/vendor/libgit2/deps/pcre/pcre_exec.c +2 -2
  14. data/vendor/libgit2/deps/xdiff/CMakeLists.txt +28 -0
  15. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/git-xdiff.h +4 -1
  16. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xdiffi.c +19 -18
  17. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xdiffi.h +2 -4
  18. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xemit.c +3 -3
  19. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xhistogram.c +7 -18
  20. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xmacros.h +18 -1
  21. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xmerge.c +24 -22
  22. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xpatience.c +21 -30
  23. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xprepare.c +13 -30
  24. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xutils.c +18 -1
  25. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xutils.h +2 -1
  26. data/vendor/libgit2/include/git2/common.h +26 -1
  27. data/vendor/libgit2/include/git2/diff.h +41 -3
  28. data/vendor/libgit2/include/git2/errors.h +4 -2
  29. data/vendor/libgit2/include/git2/index.h +9 -0
  30. data/vendor/libgit2/include/git2/oid.h +1 -1
  31. data/vendor/libgit2/include/git2/remote.h +18 -0
  32. data/vendor/libgit2/include/git2/repository.h +12 -2
  33. data/vendor/libgit2/include/git2/sys/alloc.h +0 -34
  34. data/vendor/libgit2/include/git2/sys/commit_graph.h +12 -2
  35. data/vendor/libgit2/include/git2/sys/midx.h +5 -1
  36. data/vendor/libgit2/include/git2/sys/stream.h +16 -2
  37. data/vendor/libgit2/include/git2/sys/transport.h +20 -2
  38. data/vendor/libgit2/include/git2/version.h +4 -4
  39. data/vendor/libgit2/include/git2/worktree.h +3 -1
  40. data/vendor/libgit2/src/CMakeLists.txt +34 -11
  41. data/vendor/libgit2/src/cli/cmd_clone.c +22 -6
  42. data/vendor/libgit2/src/cli/progress.c +9 -8
  43. data/vendor/libgit2/src/cli/progress.h +4 -4
  44. data/vendor/libgit2/src/libgit2/CMakeLists.txt +1 -19
  45. data/vendor/libgit2/src/libgit2/annotated_commit.c +2 -2
  46. data/vendor/libgit2/src/libgit2/annotated_commit.h +1 -1
  47. data/vendor/libgit2/src/libgit2/apply.c +4 -3
  48. data/vendor/libgit2/src/libgit2/blame.c +23 -16
  49. data/vendor/libgit2/src/libgit2/blame_git.c +0 -1
  50. data/vendor/libgit2/src/libgit2/branch.c +2 -2
  51. data/vendor/libgit2/src/libgit2/cherrypick.c +3 -3
  52. data/vendor/libgit2/src/libgit2/clone.c +3 -1
  53. data/vendor/libgit2/src/libgit2/commit.c +31 -9
  54. data/vendor/libgit2/src/libgit2/commit_graph.c +110 -43
  55. data/vendor/libgit2/src/libgit2/commit_graph.h +20 -4
  56. data/vendor/libgit2/src/libgit2/commit_list.c +12 -5
  57. data/vendor/libgit2/src/libgit2/commit_list.h +1 -0
  58. data/vendor/libgit2/src/libgit2/config.c +5 -2
  59. data/vendor/libgit2/src/libgit2/config_file.c +14 -8
  60. data/vendor/libgit2/src/libgit2/describe.c +10 -7
  61. data/vendor/libgit2/src/libgit2/diff.c +16 -7
  62. data/vendor/libgit2/src/libgit2/diff.h +6 -6
  63. data/vendor/libgit2/src/libgit2/diff_file.c +7 -7
  64. data/vendor/libgit2/src/libgit2/diff_generate.c +36 -15
  65. data/vendor/libgit2/src/libgit2/diff_parse.c +20 -4
  66. data/vendor/libgit2/src/libgit2/diff_print.c +26 -7
  67. data/vendor/libgit2/src/libgit2/diff_tform.c +4 -4
  68. data/vendor/libgit2/src/libgit2/diff_xdiff.h +1 -1
  69. data/vendor/libgit2/src/libgit2/email.c +4 -3
  70. data/vendor/libgit2/src/libgit2/errors.c +73 -18
  71. data/vendor/libgit2/src/libgit2/fetch.c +37 -9
  72. data/vendor/libgit2/src/libgit2/fetch.h +0 -2
  73. data/vendor/libgit2/src/libgit2/fetchhead.c +11 -9
  74. data/vendor/libgit2/src/libgit2/grafts.c +272 -0
  75. data/vendor/libgit2/src/libgit2/grafts.h +36 -0
  76. data/vendor/libgit2/src/libgit2/ident.c +3 -3
  77. data/vendor/libgit2/src/libgit2/index.c +323 -120
  78. data/vendor/libgit2/src/libgit2/index.h +14 -1
  79. data/vendor/libgit2/src/libgit2/indexer.c +10 -3
  80. data/vendor/libgit2/src/libgit2/iterator.c +20 -5
  81. data/vendor/libgit2/src/libgit2/iterator.h +3 -0
  82. data/vendor/libgit2/src/libgit2/libgit2.c +39 -0
  83. data/vendor/libgit2/src/libgit2/merge.c +14 -9
  84. data/vendor/libgit2/src/libgit2/merge_file.c +0 -2
  85. data/vendor/libgit2/src/libgit2/midx.c +66 -37
  86. data/vendor/libgit2/src/libgit2/midx.h +13 -3
  87. data/vendor/libgit2/src/libgit2/notes.c +9 -8
  88. data/vendor/libgit2/src/libgit2/object.c +40 -15
  89. data/vendor/libgit2/src/libgit2/object.h +6 -0
  90. data/vendor/libgit2/src/libgit2/odb.c +11 -5
  91. data/vendor/libgit2/src/libgit2/odb_pack.c +16 -3
  92. data/vendor/libgit2/src/libgit2/oid.c +7 -1
  93. data/vendor/libgit2/src/libgit2/oidarray.c +49 -3
  94. data/vendor/libgit2/src/libgit2/oidarray.h +5 -1
  95. data/vendor/libgit2/src/libgit2/pack-objects.c +19 -12
  96. data/vendor/libgit2/src/libgit2/pack-objects.h +5 -2
  97. data/vendor/libgit2/src/libgit2/pack.c +3 -3
  98. data/vendor/libgit2/src/libgit2/parse.c +7 -4
  99. data/vendor/libgit2/src/libgit2/parse.h +1 -1
  100. data/vendor/libgit2/src/libgit2/patch.h +7 -1
  101. data/vendor/libgit2/src/libgit2/patch_generate.c +24 -5
  102. data/vendor/libgit2/src/libgit2/patch_parse.c +16 -8
  103. data/vendor/libgit2/src/libgit2/push.c +2 -2
  104. data/vendor/libgit2/src/libgit2/reader.c +1 -1
  105. data/vendor/libgit2/src/libgit2/rebase.c +72 -84
  106. data/vendor/libgit2/src/libgit2/refdb_fs.c +22 -13
  107. data/vendor/libgit2/src/libgit2/refs.c +8 -1
  108. data/vendor/libgit2/src/libgit2/remote.c +15 -6
  109. data/vendor/libgit2/src/libgit2/remote.h +1 -0
  110. data/vendor/libgit2/src/libgit2/repository.c +580 -301
  111. data/vendor/libgit2/src/libgit2/repository.h +17 -2
  112. data/vendor/libgit2/src/libgit2/reset.c +2 -2
  113. data/vendor/libgit2/src/libgit2/revert.c +8 -11
  114. data/vendor/libgit2/src/libgit2/revwalk.c +26 -4
  115. data/vendor/libgit2/src/libgit2/stash.c +9 -8
  116. data/vendor/libgit2/src/libgit2/streams/mbedtls.c +0 -1
  117. data/vendor/libgit2/src/libgit2/streams/openssl.c +8 -16
  118. data/vendor/libgit2/src/libgit2/streams/schannel.c +715 -0
  119. data/vendor/libgit2/src/libgit2/streams/schannel.h +28 -0
  120. data/vendor/libgit2/src/libgit2/streams/socket.c +237 -51
  121. data/vendor/libgit2/src/libgit2/streams/socket.h +3 -1
  122. data/vendor/libgit2/src/libgit2/streams/stransport.c +40 -12
  123. data/vendor/libgit2/src/libgit2/streams/tls.c +5 -0
  124. data/vendor/libgit2/src/libgit2/submodule.h +3 -3
  125. data/vendor/libgit2/src/libgit2/threadstate.c +15 -2
  126. data/vendor/libgit2/src/libgit2/threadstate.h +1 -3
  127. data/vendor/libgit2/src/libgit2/transports/auth.h +1 -2
  128. data/vendor/libgit2/src/libgit2/transports/{auth_negotiate.c → auth_gssapi.c} +32 -32
  129. data/vendor/libgit2/src/libgit2/transports/auth_negotiate.h +1 -1
  130. data/vendor/libgit2/src/libgit2/transports/auth_ntlm.h +1 -1
  131. data/vendor/libgit2/src/libgit2/transports/{auth_ntlm.c → auth_ntlmclient.c} +12 -12
  132. data/vendor/libgit2/src/libgit2/transports/auth_sspi.c +341 -0
  133. data/vendor/libgit2/src/libgit2/transports/git.c +7 -8
  134. data/vendor/libgit2/src/libgit2/transports/http.c +7 -2
  135. data/vendor/libgit2/src/libgit2/transports/httpclient.c +5 -0
  136. data/vendor/libgit2/src/libgit2/transports/local.c +13 -4
  137. data/vendor/libgit2/src/libgit2/transports/smart.c +33 -27
  138. data/vendor/libgit2/src/libgit2/transports/smart.h +23 -8
  139. data/vendor/libgit2/src/libgit2/transports/smart_pkt.c +135 -15
  140. data/vendor/libgit2/src/libgit2/transports/smart_protocol.c +154 -47
  141. data/vendor/libgit2/src/libgit2/transports/ssh.c +3 -3
  142. data/vendor/libgit2/src/libgit2/transports/winhttp.c +14 -15
  143. data/vendor/libgit2/src/libgit2/tree-cache.c +26 -16
  144. data/vendor/libgit2/src/libgit2/tree-cache.h +5 -3
  145. data/vendor/libgit2/src/libgit2/tree.c +1 -1
  146. data/vendor/libgit2/src/libgit2/worktree.c +25 -10
  147. data/vendor/libgit2/src/util/alloc.c +65 -6
  148. data/vendor/libgit2/src/util/alloc.h +34 -9
  149. data/vendor/libgit2/src/util/allocators/failalloc.c +0 -60
  150. data/vendor/libgit2/src/util/allocators/failalloc.h +0 -6
  151. data/vendor/libgit2/src/util/allocators/stdalloc.c +2 -105
  152. data/vendor/libgit2/src/util/allocators/win32_leakcheck.c +0 -68
  153. data/vendor/libgit2/src/util/array.h +6 -1
  154. data/vendor/libgit2/src/util/cc-compat.h +2 -0
  155. data/vendor/libgit2/src/util/filebuf.c +6 -1
  156. data/vendor/libgit2/src/util/filebuf.h +19 -6
  157. data/vendor/libgit2/src/util/fs_path.c +1 -1
  158. data/vendor/libgit2/src/util/futils.c +8 -5
  159. data/vendor/libgit2/src/util/git2_features.h.in +9 -3
  160. data/vendor/libgit2/src/util/net.c +308 -157
  161. data/vendor/libgit2/src/util/net.h +25 -0
  162. data/vendor/libgit2/src/util/posix.c +54 -0
  163. data/vendor/libgit2/src/util/posix.h +22 -0
  164. data/vendor/libgit2/src/util/rand.c +6 -4
  165. data/vendor/libgit2/src/util/staticstr.h +66 -0
  166. data/vendor/libgit2/src/util/util.c +15 -10
  167. data/vendor/libgit2/src/util/util.h +24 -16
  168. data/vendor/libgit2/src/util/win32/error.c +1 -1
  169. data/vendor/libgit2/src/util/win32/path_w32.c +8 -8
  170. data/vendor/libgit2/src/util/win32/posix_w32.c +1 -1
  171. data/vendor/libgit2/src/util/win32/utf-conv.c +73 -75
  172. data/vendor/libgit2/src/util/win32/utf-conv.h +81 -14
  173. data/vendor/libgit2/src/util/win32/w32_util.c +1 -1
  174. metadata +29 -23
  175. data/vendor/libgit2/cmake/SelectWinHTTP.cmake +0 -17
  176. data/vendor/libgit2/src/libgit2/netops.c +0 -124
  177. data/vendor/libgit2/src/libgit2/netops.h +0 -68
  178. /data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xdiff.h +0 -0
  179. /data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xemit.h +0 -0
  180. /data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xinclude.h +0 -0
  181. /data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xprepare.h +0 -0
  182. /data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xtypes.h +0 -0
@@ -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;
@@ -2306,6 +2343,7 @@ static int index_error_invalid(const char *message)
2306
2343
  static int read_reuc(git_index *index, const char *buffer, size_t size)
2307
2344
  {
2308
2345
  const char *endptr;
2346
+ size_t oid_size = git_oid_size(index->oid_type);
2309
2347
  size_t len;
2310
2348
  int i;
2311
2349
 
@@ -2354,16 +2392,16 @@ static int read_reuc(git_index *index, const char *buffer, size_t size)
2354
2392
  for (i = 0; i < 3; i++) {
2355
2393
  if (!lost->mode[i])
2356
2394
  continue;
2357
- if (size < GIT_OID_SHA1_SIZE) {
2395
+ if (size < oid_size) {
2358
2396
  index_entry_reuc_free(lost);
2359
2397
  return index_error_invalid("reading reuc entry oid");
2360
2398
  }
2361
2399
 
2362
- if (git_oid__fromraw(&lost->oid[i], (const unsigned char *) buffer, GIT_OID_SHA1) < 0)
2400
+ if (git_oid__fromraw(&lost->oid[i], (const unsigned char *) buffer, index->oid_type) < 0)
2363
2401
  return -1;
2364
2402
 
2365
- size -= GIT_OID_SHA1_SIZE;
2366
- buffer += GIT_OID_SHA1_SIZE;
2403
+ size -= oid_size;
2404
+ buffer += oid_size;
2367
2405
  }
2368
2406
 
2369
2407
  /* entry was read successfully - insert into reuc vector */
@@ -2433,73 +2471,157 @@ out_err:
2433
2471
  return 0;
2434
2472
  }
2435
2473
 
2436
- static size_t index_entry_size(size_t path_len, size_t varint_len, uint32_t flags)
2474
+ GIT_INLINE(size_t) index_entry_path_offset(
2475
+ git_oid_t oid_type,
2476
+ uint32_t flags)
2477
+ {
2478
+ if (oid_type == GIT_OID_SHA1)
2479
+ return (flags & GIT_INDEX_ENTRY_EXTENDED) ?
2480
+ offsetof(index_entry_long_sha1, path) :
2481
+ offsetof(index_entry_short_sha1, path);
2482
+
2483
+ #ifdef GIT_EXPERIMENTAL_SHA256
2484
+ else if (oid_type == GIT_OID_SHA256)
2485
+ return (flags & GIT_INDEX_ENTRY_EXTENDED) ?
2486
+ offsetof(index_entry_long_sha256, path) :
2487
+ offsetof(index_entry_short_sha256, path);
2488
+ #endif
2489
+
2490
+ git_error_set(GIT_ERROR_INTERNAL, "invalid oid type");
2491
+ return 0;
2492
+ }
2493
+
2494
+ GIT_INLINE(size_t) index_entry_flags_offset(git_oid_t oid_type)
2437
2495
  {
2496
+ if (oid_type == GIT_OID_SHA1)
2497
+ return offsetof(index_entry_long_sha1, flags_extended);
2498
+
2499
+ #ifdef GIT_EXPERIMENTAL_SHA256
2500
+ else if (oid_type == GIT_OID_SHA256)
2501
+ return offsetof(index_entry_long_sha256, flags_extended);
2502
+ #endif
2503
+
2504
+ git_error_set(GIT_ERROR_INTERNAL, "invalid oid type");
2505
+ return 0;
2506
+ }
2507
+
2508
+ static size_t index_entry_size(
2509
+ size_t path_len,
2510
+ size_t varint_len,
2511
+ git_oid_t oid_type,
2512
+ uint32_t flags)
2513
+ {
2514
+ size_t offset, size;
2515
+
2516
+ if (!(offset = index_entry_path_offset(oid_type, flags)))
2517
+ return 0;
2518
+
2438
2519
  if (varint_len) {
2439
- if (flags & GIT_INDEX_ENTRY_EXTENDED)
2440
- return offsetof(struct entry_long, path) + path_len + 1 + varint_len;
2441
- else
2442
- return offsetof(struct entry_short, path) + path_len + 1 + varint_len;
2520
+ if (GIT_ADD_SIZET_OVERFLOW(&size, offset, path_len) ||
2521
+ GIT_ADD_SIZET_OVERFLOW(&size, size, 1) ||
2522
+ GIT_ADD_SIZET_OVERFLOW(&size, size, varint_len))
2523
+ return 0;
2443
2524
  } else {
2444
- #define entry_size(type,len) ((offsetof(type, path) + (len) + 8) & ~7)
2445
- if (flags & GIT_INDEX_ENTRY_EXTENDED)
2446
- return entry_size(struct entry_long, path_len);
2447
- else
2448
- return entry_size(struct entry_short, path_len);
2449
- #undef entry_size
2525
+ if (GIT_ADD_SIZET_OVERFLOW(&size, offset, path_len) ||
2526
+ GIT_ADD_SIZET_OVERFLOW(&size, size, 8))
2527
+ return 0;
2528
+
2529
+ size &= ~7;
2450
2530
  }
2531
+
2532
+ return size;
2451
2533
  }
2452
2534
 
2453
2535
  static int read_entry(
2454
2536
  git_index_entry **out,
2455
2537
  size_t *out_size,
2456
2538
  git_index *index,
2539
+ size_t checksum_size,
2457
2540
  const void *buffer,
2458
2541
  size_t buffer_size,
2459
2542
  const char *last)
2460
2543
  {
2461
- size_t path_length, entry_size;
2544
+ size_t path_length, path_offset, entry_size;
2462
2545
  const char *path_ptr;
2463
- struct entry_short source;
2546
+ struct entry_common *source_common;
2547
+ index_entry_short_sha1 source_sha1;
2548
+ #ifdef GIT_EXPERIMENTAL_SHA256
2549
+ index_entry_short_sha256 source_sha256;
2550
+ #endif
2464
2551
  git_index_entry entry = {{0}};
2465
2552
  bool compressed = index->version >= INDEX_VERSION_NUMBER_COMP;
2466
2553
  char *tmp_path = NULL;
2467
- size_t checksum_size = GIT_HASH_SHA1_SIZE;
2554
+
2555
+ size_t minimal_entry_size = index_entry_path_offset(index->oid_type, 0);
2468
2556
 
2469
2557
  if (checksum_size + minimal_entry_size > buffer_size)
2470
2558
  return -1;
2471
2559
 
2472
2560
  /* buffer is not guaranteed to be aligned */
2473
- memcpy(&source, buffer, sizeof(struct entry_short));
2474
-
2475
- entry.ctime.seconds = (git_time_t)ntohl(source.ctime.seconds);
2476
- entry.ctime.nanoseconds = ntohl(source.ctime.nanoseconds);
2477
- entry.mtime.seconds = (git_time_t)ntohl(source.mtime.seconds);
2478
- entry.mtime.nanoseconds = ntohl(source.mtime.nanoseconds);
2479
- entry.dev = ntohl(source.dev);
2480
- entry.ino = ntohl(source.ino);
2481
- entry.mode = ntohl(source.mode);
2482
- entry.uid = ntohl(source.uid);
2483
- entry.gid = ntohl(source.gid);
2484
- entry.file_size = ntohl(source.file_size);
2485
- entry.flags = ntohs(source.flags);
2486
-
2487
- if (git_oid__fromraw(&entry.id, source.oid, GIT_OID_SHA1) < 0)
2561
+ switch (index->oid_type) {
2562
+ case GIT_OID_SHA1:
2563
+ source_common = &source_sha1.common;
2564
+ memcpy(&source_sha1, buffer, sizeof(source_sha1));
2565
+ break;
2566
+ #ifdef GIT_EXPERIMENTAL_SHA256
2567
+ case GIT_OID_SHA256:
2568
+ source_common = &source_sha256.common;
2569
+ memcpy(&source_sha256, buffer, sizeof(source_sha256));
2570
+ break;
2571
+ #endif
2572
+ default:
2573
+ GIT_ASSERT(!"invalid oid type");
2574
+ }
2575
+
2576
+ entry.ctime.seconds = (git_time_t)ntohl(source_common->ctime.seconds);
2577
+ entry.ctime.nanoseconds = ntohl(source_common->ctime.nanoseconds);
2578
+ entry.mtime.seconds = (git_time_t)ntohl(source_common->mtime.seconds);
2579
+ entry.mtime.nanoseconds = ntohl(source_common->mtime.nanoseconds);
2580
+ entry.dev = ntohl(source_common->dev);
2581
+ entry.ino = ntohl(source_common->ino);
2582
+ entry.mode = ntohl(source_common->mode);
2583
+ entry.uid = ntohl(source_common->uid);
2584
+ entry.gid = ntohl(source_common->gid);
2585
+ entry.file_size = ntohl(source_common->file_size);
2586
+
2587
+ switch (index->oid_type) {
2588
+ case GIT_OID_SHA1:
2589
+ if (git_oid__fromraw(&entry.id, source_sha1.oid,
2590
+ GIT_OID_SHA1) < 0)
2591
+ return -1;
2592
+ entry.flags = ntohs(source_sha1.flags);
2593
+ break;
2594
+ #ifdef GIT_EXPERIMENTAL_SHA256
2595
+ case GIT_OID_SHA256:
2596
+ if (git_oid__fromraw(&entry.id, source_sha256.oid,
2597
+ GIT_OID_SHA256) < 0)
2598
+ return -1;
2599
+ entry.flags = ntohs(source_sha256.flags);
2600
+ break;
2601
+ #endif
2602
+ default:
2603
+ GIT_ASSERT(!"invalid oid type");
2604
+ }
2605
+
2606
+ if (!(path_offset = index_entry_path_offset(index->oid_type, entry.flags)))
2488
2607
  return -1;
2489
2608
 
2609
+
2490
2610
  if (entry.flags & GIT_INDEX_ENTRY_EXTENDED) {
2491
2611
  uint16_t flags_raw;
2492
2612
  size_t flags_offset;
2493
2613
 
2494
- flags_offset = offsetof(struct entry_long, flags_extended);
2495
- memcpy(&flags_raw, (const char *) buffer + flags_offset,
2496
- sizeof(flags_raw));
2614
+ if (!(flags_offset = index_entry_flags_offset(index->oid_type)))
2615
+ return -1;
2616
+
2617
+ memcpy(&flags_raw, (const char *)buffer + flags_offset, sizeof(flags_raw));
2497
2618
  flags_raw = ntohs(flags_raw);
2498
2619
 
2499
2620
  memcpy(&entry.flags_extended, &flags_raw, sizeof(flags_raw));
2500
- path_ptr = (const char *) buffer + offsetof(struct entry_long, path);
2501
- } else
2502
- path_ptr = (const char *) buffer + offsetof(struct entry_short, path);
2621
+ path_ptr = (const char *)buffer + path_offset;
2622
+ } else {
2623
+ path_ptr = (const char *)buffer + path_offset;
2624
+ }
2503
2625
 
2504
2626
  if (!compressed) {
2505
2627
  path_length = entry.flags & GIT_INDEX_ENTRY_NAMEMASK;
@@ -2511,12 +2633,12 @@ static int read_entry(
2511
2633
 
2512
2634
  path_end = memchr(path_ptr, '\0', buffer_size);
2513
2635
  if (path_end == NULL)
2514
- return -1;
2636
+ return index_error_invalid("invalid path name");
2515
2637
 
2516
2638
  path_length = path_end - path_ptr;
2517
2639
  }
2518
2640
 
2519
- entry_size = index_entry_size(path_length, 0, entry.flags);
2641
+ entry_size = index_entry_size(path_length, 0, index->oid_type, entry.flags);
2520
2642
  entry.path = (char *)path_ptr;
2521
2643
  } else {
2522
2644
  size_t varint_len, last_len, prefix_len, suffix_len, path_len;
@@ -2542,15 +2664,18 @@ static int read_entry(
2542
2664
 
2543
2665
  memcpy(tmp_path, last, prefix_len);
2544
2666
  memcpy(tmp_path + prefix_len, path_ptr + varint_len, suffix_len + 1);
2545
- entry_size = index_entry_size(suffix_len, varint_len, entry.flags);
2667
+
2668
+ entry_size = index_entry_size(suffix_len, varint_len, index->oid_type, entry.flags);
2546
2669
  entry.path = tmp_path;
2547
2670
  }
2548
2671
 
2549
2672
  if (entry_size == 0)
2550
2673
  return -1;
2551
2674
 
2552
- if (checksum_size + entry_size > buffer_size)
2675
+ if (checksum_size + entry_size > buffer_size) {
2676
+ git_error_set(GIT_ERROR_INTERNAL, "invalid index checksum");
2553
2677
  return -1;
2678
+ }
2554
2679
 
2555
2680
  if (index_entry_dup(out, index, &entry) < 0) {
2556
2681
  git__free(tmp_path);
@@ -2579,11 +2704,10 @@ static int read_header(struct index_header *dest, const void *buffer)
2579
2704
  return 0;
2580
2705
  }
2581
2706
 
2582
- static int read_extension(size_t *read_len, git_index *index, const char *buffer, size_t buffer_size)
2707
+ static int read_extension(size_t *read_len, git_index *index, size_t checksum_size, const char *buffer, size_t buffer_size)
2583
2708
  {
2584
2709
  struct index_extension dest;
2585
2710
  size_t total_size;
2586
- size_t checksum_size = GIT_HASH_SHA1_SIZE;
2587
2711
 
2588
2712
  /* buffer is not guaranteed to be aligned */
2589
2713
  memcpy(&dest, buffer, sizeof(struct index_extension));
@@ -2602,7 +2726,7 @@ static int read_extension(size_t *read_len, git_index *index, const char *buffer
2602
2726
  if (dest.signature[0] >= 'A' && dest.signature[0] <= 'Z') {
2603
2727
  /* tree cache */
2604
2728
  if (memcmp(dest.signature, INDEX_EXT_TREECACHE_SIG, 4) == 0) {
2605
- if (git_tree_cache_read(&index->tree, buffer + 8, dest.extension_size, &index->tree_pool) < 0)
2729
+ if (git_tree_cache_read(&index->tree, buffer + 8, dest.extension_size, index->oid_type, &index->tree_pool) < 0)
2606
2730
  return -1;
2607
2731
  } else if (memcmp(dest.signature, INDEX_EXT_UNMERGED_SIG, 4) == 0) {
2608
2732
  if (read_reuc(index, buffer + 8, dest.extension_size) < 0)
@@ -2630,8 +2754,8 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size)
2630
2754
  int error = 0;
2631
2755
  unsigned int i;
2632
2756
  struct index_header header = { 0 };
2633
- unsigned char checksum[GIT_HASH_SHA1_SIZE];
2634
- size_t checksum_size = GIT_HASH_SHA1_SIZE;
2757
+ unsigned char checksum[GIT_HASH_MAX_SIZE];
2758
+ size_t checksum_size = git_hash_size(git_oid_algorithm(index->oid_type));
2635
2759
  const char *last = NULL;
2636
2760
  const char *empty = "";
2637
2761
 
@@ -2646,9 +2770,12 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size)
2646
2770
  if (buffer_size < INDEX_HEADER_SIZE + checksum_size)
2647
2771
  return index_error_invalid("insufficient buffer space");
2648
2772
 
2649
- /* Precalculate the SHA1 of the files's contents -- we'll match it to
2650
- * the provided SHA1 in the footer */
2651
- git_hash_buf(checksum, buffer, buffer_size - checksum_size, GIT_HASH_ALGORITHM_SHA1);
2773
+ /*
2774
+ * Precalculate the hash of the files's contents -- we'll match
2775
+ * it to the provided checksum in the footer.
2776
+ */
2777
+ git_hash_buf(checksum, buffer, buffer_size - checksum_size,
2778
+ git_oid_algorithm(index->oid_type));
2652
2779
 
2653
2780
  /* Parse header */
2654
2781
  if ((error = read_header(&header, buffer)) < 0)
@@ -2670,7 +2797,7 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size)
2670
2797
  git_index_entry *entry = NULL;
2671
2798
  size_t entry_size;
2672
2799
 
2673
- if ((error = read_entry(&entry, &entry_size, index, buffer, buffer_size, last)) < 0) {
2800
+ if ((error = read_entry(&entry, &entry_size, index, checksum_size, buffer, buffer_size, last)) < 0) {
2674
2801
  error = index_error_invalid("invalid entry");
2675
2802
  goto done;
2676
2803
  }
@@ -2701,7 +2828,7 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size)
2701
2828
  while (buffer_size > checksum_size) {
2702
2829
  size_t extension_size;
2703
2830
 
2704
- if ((error = read_extension(&extension_size, index, buffer, buffer_size)) < 0) {
2831
+ if ((error = read_extension(&extension_size, index, checksum_size, buffer, buffer_size)) < 0) {
2705
2832
  goto done;
2706
2833
  }
2707
2834
 
@@ -2714,7 +2841,10 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size)
2714
2841
  goto done;
2715
2842
  }
2716
2843
 
2717
- /* 160-bit SHA-1 over the content of the index file before this checksum. */
2844
+ /*
2845
+ * SHA-1 or SHA-256 (depending on the repository's object format)
2846
+ * over the content of the index file before this checksum.
2847
+ */
2718
2848
  if (memcmp(checksum, buffer, checksum_size) != 0) {
2719
2849
  error = index_error_invalid(
2720
2850
  "calculated checksum does not match expected");
@@ -2754,16 +2884,40 @@ static bool is_index_extended(git_index *index)
2754
2884
  return (extended > 0);
2755
2885
  }
2756
2886
 
2757
- static int write_disk_entry(git_filebuf *file, git_index_entry *entry, const char *last)
2887
+ static int write_disk_entry(
2888
+ git_index *index,
2889
+ git_filebuf *file,
2890
+ git_index_entry *entry,
2891
+ const char *last)
2758
2892
  {
2759
2893
  void *mem = NULL;
2760
- struct entry_short ondisk;
2761
- size_t path_len, disk_size;
2894
+ struct entry_common *ondisk_common;
2895
+ size_t path_len, path_offset, disk_size;
2762
2896
  int varint_len = 0;
2763
2897
  char *path;
2764
2898
  const char *path_start = entry->path;
2765
2899
  size_t same_len = 0;
2766
2900
 
2901
+ index_entry_short_sha1 ondisk_sha1;
2902
+ index_entry_long_sha1 ondisk_ext_sha1;
2903
+ #ifdef GIT_EXPERIMENTAL_SHA256
2904
+ index_entry_short_sha256 ondisk_sha256;
2905
+ index_entry_long_sha256 ondisk_ext_sha256;
2906
+ #endif
2907
+
2908
+ switch (index->oid_type) {
2909
+ case GIT_OID_SHA1:
2910
+ ondisk_common = &ondisk_sha1.common;
2911
+ break;
2912
+ #ifdef GIT_EXPERIMENTAL_SHA256
2913
+ case GIT_OID_SHA256:
2914
+ ondisk_common = &ondisk_sha256.common;
2915
+ break;
2916
+ #endif
2917
+ default:
2918
+ GIT_ASSERT(!"invalid oid type");
2919
+ }
2920
+
2767
2921
  path_len = ((struct entry_internal *)entry)->pathlen;
2768
2922
 
2769
2923
  if (last) {
@@ -2780,9 +2934,9 @@ static int write_disk_entry(git_filebuf *file, git_index_entry *entry, const cha
2780
2934
  varint_len = git_encode_varint(NULL, 0, strlen(last) - same_len);
2781
2935
  }
2782
2936
 
2783
- disk_size = index_entry_size(path_len, varint_len, entry->flags);
2937
+ disk_size = index_entry_size(path_len, varint_len, index->oid_type, entry->flags);
2784
2938
 
2785
- if (git_filebuf_reserve(file, &mem, disk_size) < 0)
2939
+ if (!disk_size || git_filebuf_reserve(file, &mem, disk_size) < 0)
2786
2940
  return -1;
2787
2941
 
2788
2942
  memset(mem, 0x0, disk_size);
@@ -2797,35 +2951,77 @@ static int write_disk_entry(git_filebuf *file, git_index_entry *entry, const cha
2797
2951
  *
2798
2952
  * In 2038 I will be either too dead or too rich to care about this
2799
2953
  */
2800
- ondisk.ctime.seconds = htonl((uint32_t)entry->ctime.seconds);
2801
- ondisk.mtime.seconds = htonl((uint32_t)entry->mtime.seconds);
2802
- ondisk.ctime.nanoseconds = htonl(entry->ctime.nanoseconds);
2803
- ondisk.mtime.nanoseconds = htonl(entry->mtime.nanoseconds);
2804
- ondisk.dev = htonl(entry->dev);
2805
- ondisk.ino = htonl(entry->ino);
2806
- ondisk.mode = htonl(entry->mode);
2807
- ondisk.uid = htonl(entry->uid);
2808
- ondisk.gid = htonl(entry->gid);
2809
- ondisk.file_size = htonl((uint32_t)entry->file_size);
2810
- git_oid_raw_cpy(ondisk.oid, entry->id.id, GIT_OID_SHA1_SIZE);
2811
- ondisk.flags = htons(entry->flags);
2954
+ ondisk_common->ctime.seconds = htonl((uint32_t)entry->ctime.seconds);
2955
+ ondisk_common->mtime.seconds = htonl((uint32_t)entry->mtime.seconds);
2956
+ ondisk_common->ctime.nanoseconds = htonl(entry->ctime.nanoseconds);
2957
+ ondisk_common->mtime.nanoseconds = htonl(entry->mtime.nanoseconds);
2958
+ ondisk_common->dev = htonl(entry->dev);
2959
+ ondisk_common->ino = htonl(entry->ino);
2960
+ ondisk_common->mode = htonl(entry->mode);
2961
+ ondisk_common->uid = htonl(entry->uid);
2962
+ ondisk_common->gid = htonl(entry->gid);
2963
+ ondisk_common->file_size = htonl((uint32_t)entry->file_size);
2964
+
2965
+ switch (index->oid_type) {
2966
+ case GIT_OID_SHA1:
2967
+ git_oid_raw_cpy(ondisk_sha1.oid, entry->id.id, GIT_OID_SHA1_SIZE);
2968
+ ondisk_sha1.flags = htons(entry->flags);
2969
+ break;
2970
+ #ifdef GIT_EXPERIMENTAL_SHA256
2971
+ case GIT_OID_SHA256:
2972
+ git_oid_raw_cpy(ondisk_sha256.oid, entry->id.id, GIT_OID_SHA256_SIZE);
2973
+ ondisk_sha256.flags = htons(entry->flags);
2974
+ break;
2975
+ #endif
2976
+ default:
2977
+ GIT_ASSERT(!"invalid oid type");
2978
+ }
2979
+
2980
+ path_offset = index_entry_path_offset(index->oid_type, entry->flags);
2812
2981
 
2813
2982
  if (entry->flags & GIT_INDEX_ENTRY_EXTENDED) {
2814
- const size_t path_offset = offsetof(struct entry_long, path);
2815
- struct entry_long ondisk_ext;
2816
- memcpy(&ondisk_ext, &ondisk, sizeof(struct entry_short));
2817
- ondisk_ext.flags_extended = htons(entry->flags_extended &
2983
+ struct entry_common *ondisk_ext;
2984
+ uint16_t flags_extended = htons(entry->flags_extended &
2818
2985
  GIT_INDEX_ENTRY_EXTENDED_FLAGS);
2819
- memcpy(mem, &ondisk_ext, path_offset);
2820
- path = (char *)mem + path_offset;
2821
- disk_size -= path_offset;
2986
+
2987
+ switch (index->oid_type) {
2988
+ case GIT_OID_SHA1:
2989
+ memcpy(&ondisk_ext_sha1, &ondisk_sha1,
2990
+ sizeof(index_entry_short_sha1));
2991
+ ondisk_ext_sha1.flags_extended = flags_extended;
2992
+ ondisk_ext = &ondisk_ext_sha1.common;
2993
+ break;
2994
+ #ifdef GIT_EXPERIMENTAL_SHA256
2995
+ case GIT_OID_SHA256:
2996
+ memcpy(&ondisk_ext_sha256, &ondisk_sha256,
2997
+ sizeof(index_entry_short_sha256));
2998
+ ondisk_ext_sha256.flags_extended = flags_extended;
2999
+ ondisk_ext = &ondisk_ext_sha256.common;
3000
+ break;
3001
+ #endif
3002
+ default:
3003
+ GIT_ASSERT(!"invalid oid type");
3004
+ }
3005
+
3006
+ memcpy(mem, ondisk_ext, path_offset);
2822
3007
  } else {
2823
- const size_t path_offset = offsetof(struct entry_short, path);
2824
- memcpy(mem, &ondisk, path_offset);
2825
- path = (char *)mem + path_offset;
2826
- disk_size -= path_offset;
3008
+ switch (index->oid_type) {
3009
+ case GIT_OID_SHA1:
3010
+ memcpy(mem, &ondisk_sha1, path_offset);
3011
+ break;
3012
+ #ifdef GIT_EXPERIMENTAL_SHA256
3013
+ case GIT_OID_SHA256:
3014
+ memcpy(mem, &ondisk_sha256, path_offset);
3015
+ break;
3016
+ #endif
3017
+ default:
3018
+ GIT_ASSERT(!"invalid oid type");
3019
+ }
2827
3020
  }
2828
3021
 
3022
+ path = (char *)mem + path_offset;
3023
+ disk_size -= path_offset;
3024
+
2829
3025
  if (last) {
2830
3026
  varint_len = git_encode_varint((unsigned char *) path,
2831
3027
  disk_size, strlen(last) - same_len);
@@ -2877,7 +3073,7 @@ static int write_entries(git_index *index, git_filebuf *file)
2877
3073
  last = "";
2878
3074
 
2879
3075
  git_vector_foreach(entries, i, entry) {
2880
- if ((error = write_disk_entry(file, entry, last)) < 0)
3076
+ if ((error = write_disk_entry(index, file, entry, last)) < 0)
2881
3077
  break;
2882
3078
  if (index->version >= INDEX_VERSION_NUMBER_COMP)
2883
3079
  last = entry->path;
@@ -2955,8 +3151,9 @@ done:
2955
3151
  return error;
2956
3152
  }
2957
3153
 
2958
- static int create_reuc_extension_data(git_str *reuc_buf, git_index_reuc_entry *reuc)
3154
+ static int create_reuc_extension_data(git_str *reuc_buf, git_index *index, git_index_reuc_entry *reuc)
2959
3155
  {
3156
+ size_t oid_size = git_oid_size(index->oid_type);
2960
3157
  int i;
2961
3158
  int error = 0;
2962
3159
 
@@ -2970,7 +3167,7 @@ static int create_reuc_extension_data(git_str *reuc_buf, git_index_reuc_entry *r
2970
3167
  }
2971
3168
 
2972
3169
  for (i = 0; i < 3; i++) {
2973
- if (reuc->mode[i] && (error = git_str_put(reuc_buf, (char *)&reuc->oid[i].id, GIT_OID_SHA1_SIZE)) < 0)
3170
+ if (reuc->mode[i] && (error = git_str_put(reuc_buf, (char *)&reuc->oid[i].id, oid_size)) < 0)
2974
3171
  return error;
2975
3172
  }
2976
3173
 
@@ -2987,7 +3184,7 @@ static int write_reuc_extension(git_index *index, git_filebuf *file)
2987
3184
  int error = 0;
2988
3185
 
2989
3186
  git_vector_foreach(out, i, reuc) {
2990
- if ((error = create_reuc_extension_data(&reuc_buf, reuc)) < 0)
3187
+ if ((error = create_reuc_extension_data(&reuc_buf, index, reuc)) < 0)
2991
3188
  goto done;
2992
3189
  }
2993
3190
 
@@ -3036,7 +3233,7 @@ static void clear_uptodate(git_index *index)
3036
3233
  }
3037
3234
 
3038
3235
  static int write_index(
3039
- unsigned char checksum[GIT_HASH_SHA1_SIZE],
3236
+ unsigned char checksum[GIT_HASH_MAX_SIZE],
3040
3237
  size_t *checksum_size,
3041
3238
  git_index *index,
3042
3239
  git_filebuf *file)
@@ -3048,7 +3245,9 @@ static int write_index(
3048
3245
  GIT_ASSERT_ARG(index);
3049
3246
  GIT_ASSERT_ARG(file);
3050
3247
 
3051
- *checksum_size = GIT_HASH_SHA1_SIZE;
3248
+ GIT_ASSERT(index->oid_type);
3249
+
3250
+ *checksum_size = git_hash_size(git_oid_algorithm(index->oid_type));
3052
3251
 
3053
3252
  if (index->version <= INDEX_VERSION_NUMBER_EXT) {
3054
3253
  is_extended = is_index_extended(index);
@@ -3209,7 +3408,7 @@ cleanup:
3209
3408
  if (error < 0)
3210
3409
  return error;
3211
3410
 
3212
- error = git_tree_cache_read_tree(&index->tree, tree, &index->tree_pool);
3411
+ error = git_tree_cache_read_tree(&index->tree, tree, index->oid_type, &index->tree_pool);
3213
3412
 
3214
3413
  return error;
3215
3414
  }
@@ -3668,19 +3867,23 @@ int git_indexwriter_init(
3668
3867
  git_indexwriter *writer,
3669
3868
  git_index *index)
3670
3869
  {
3671
- int error;
3870
+ int filebuf_hash, error;
3672
3871
 
3673
3872
  GIT_REFCOUNT_INC(index);
3674
3873
 
3675
3874
  writer->index = index;
3676
3875
 
3876
+ filebuf_hash = git_filebuf_hash_flags(git_oid_algorithm(index->oid_type));
3877
+ GIT_ASSERT(filebuf_hash);
3878
+
3677
3879
  if (!index->index_file_path)
3678
3880
  return create_index_error(-1,
3679
3881
  "failed to write index: The index is in-memory only");
3680
3882
 
3681
- if ((error = git_filebuf_open(
3682
- &writer->file, index->index_file_path, GIT_FILEBUF_HASH_CONTENTS, GIT_INDEX_FILE_MODE)) < 0) {
3683
-
3883
+ if ((error = git_filebuf_open(&writer->file,
3884
+ index->index_file_path,
3885
+ git_filebuf_hash_flags(filebuf_hash),
3886
+ GIT_INDEX_FILE_MODE)) < 0) {
3684
3887
  if (error == GIT_ELOCKED)
3685
3888
  git_error_set(GIT_ERROR_INDEX, "the index is locked; this might be due to a concurrent or crashed process");
3686
3889
 
@@ -3712,7 +3915,7 @@ int git_indexwriter_init_for_operation(
3712
3915
 
3713
3916
  int git_indexwriter_commit(git_indexwriter *writer)
3714
3917
  {
3715
- unsigned char checksum[GIT_HASH_SHA1_SIZE];
3918
+ unsigned char checksum[GIT_HASH_MAX_SIZE];
3716
3919
  size_t checksum_size;
3717
3920
  int error;
3718
3921