rugged 1.5.0.1 → 1.7.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (250) hide show
  1. checksums.yaml +4 -4
  2. data/ext/rugged/extconf.rb +2 -2
  3. data/ext/rugged/rugged_allocator.c +0 -54
  4. data/ext/rugged/rugged_blame.c +2 -0
  5. data/ext/rugged/rugged_blob.c +3 -0
  6. data/ext/rugged/rugged_commit.c +1 -0
  7. data/ext/rugged/rugged_config.c +2 -0
  8. data/ext/rugged/rugged_diff.c +1 -0
  9. data/ext/rugged/rugged_index.c +2 -0
  10. data/ext/rugged/rugged_patch.c +1 -0
  11. data/ext/rugged/rugged_rebase.c +1 -0
  12. data/ext/rugged/rugged_reference.c +1 -0
  13. data/ext/rugged/rugged_remote.c +1 -0
  14. data/ext/rugged/rugged_repo.c +5 -2
  15. data/ext/rugged/rugged_revwalk.c +5 -1
  16. data/ext/rugged/rugged_submodule.c +1 -0
  17. data/ext/rugged/rugged_tag.c +1 -0
  18. data/ext/rugged/rugged_tree.c +4 -0
  19. data/lib/rugged/index.rb +1 -1
  20. data/lib/rugged/tree.rb +1 -1
  21. data/lib/rugged/version.rb +1 -1
  22. data/vendor/libgit2/CMakeLists.txt +7 -8
  23. data/vendor/libgit2/COPYING +30 -0
  24. data/vendor/libgit2/cmake/CheckPrototypeDefinitionSafe.cmake +16 -0
  25. data/vendor/libgit2/cmake/ExperimentalFeatures.cmake +23 -0
  26. data/vendor/libgit2/cmake/SelectGSSAPI.cmake +3 -3
  27. data/vendor/libgit2/cmake/SelectHTTPSBackend.cmake +21 -2
  28. data/vendor/libgit2/cmake/SelectHashes.cmake +4 -0
  29. data/vendor/libgit2/cmake/SelectXdiff.cmake +9 -0
  30. data/vendor/libgit2/deps/ntlmclient/CMakeLists.txt +2 -0
  31. data/vendor/libgit2/deps/pcre/LICENCE +5 -5
  32. data/vendor/libgit2/deps/pcre/pcre.h +2 -2
  33. data/vendor/libgit2/deps/pcre/pcre_compile.c +6 -3
  34. data/vendor/libgit2/deps/pcre/pcre_exec.c +2 -2
  35. data/vendor/libgit2/deps/xdiff/CMakeLists.txt +28 -0
  36. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/git-xdiff.h +4 -1
  37. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xdiffi.c +19 -18
  38. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xdiffi.h +2 -4
  39. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xemit.c +3 -3
  40. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xhistogram.c +7 -18
  41. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xmacros.h +18 -1
  42. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xmerge.c +24 -22
  43. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xpatience.c +21 -30
  44. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xprepare.c +13 -30
  45. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xutils.c +18 -1
  46. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xutils.h +2 -1
  47. data/vendor/libgit2/include/git2/common.h +38 -6
  48. data/vendor/libgit2/include/git2/deprecated.h +6 -0
  49. data/vendor/libgit2/include/git2/diff.h +42 -4
  50. data/vendor/libgit2/include/git2/errors.h +4 -2
  51. data/vendor/libgit2/include/git2/experimental.h +20 -0
  52. data/vendor/libgit2/include/git2/index.h +9 -0
  53. data/vendor/libgit2/include/git2/indexer.h +29 -0
  54. data/vendor/libgit2/include/git2/object.h +28 -2
  55. data/vendor/libgit2/include/git2/odb.h +58 -7
  56. data/vendor/libgit2/include/git2/odb_backend.h +106 -18
  57. data/vendor/libgit2/include/git2/oid.h +116 -16
  58. data/vendor/libgit2/include/git2/remote.h +18 -0
  59. data/vendor/libgit2/include/git2/repository.h +32 -3
  60. data/vendor/libgit2/include/git2/stash.h +60 -6
  61. data/vendor/libgit2/include/git2/strarray.h +0 -13
  62. data/vendor/libgit2/include/git2/sys/alloc.h +0 -34
  63. data/vendor/libgit2/include/git2/sys/commit_graph.h +12 -2
  64. data/vendor/libgit2/include/git2/sys/midx.h +5 -1
  65. data/vendor/libgit2/include/git2/sys/odb_backend.h +1 -1
  66. data/vendor/libgit2/include/git2/sys/stream.h +16 -2
  67. data/vendor/libgit2/include/git2/sys/transport.h +32 -2
  68. data/vendor/libgit2/include/git2/version.h +4 -4
  69. data/vendor/libgit2/include/git2/worktree.h +3 -1
  70. data/vendor/libgit2/include/git2.h +1 -0
  71. data/vendor/libgit2/src/CMakeLists.txt +34 -17
  72. data/vendor/libgit2/src/cli/CMakeLists.txt +5 -2
  73. data/vendor/libgit2/src/cli/cmd_clone.c +22 -6
  74. data/vendor/libgit2/src/cli/cmd_hash_object.c +27 -8
  75. data/vendor/libgit2/src/cli/opt.c +1 -1
  76. data/vendor/libgit2/src/cli/progress.c +9 -8
  77. data/vendor/libgit2/src/cli/progress.h +4 -4
  78. data/vendor/libgit2/src/libgit2/CMakeLists.txt +25 -34
  79. data/vendor/libgit2/src/libgit2/annotated_commit.c +2 -2
  80. data/vendor/libgit2/src/libgit2/annotated_commit.h +1 -1
  81. data/vendor/libgit2/src/libgit2/apply.c +4 -3
  82. data/vendor/libgit2/src/libgit2/attr_file.c +1 -1
  83. data/vendor/libgit2/src/libgit2/attrcache.c +1 -1
  84. data/vendor/libgit2/src/libgit2/blame.c +23 -14
  85. data/vendor/libgit2/src/libgit2/blame_git.c +0 -1
  86. data/vendor/libgit2/src/libgit2/blob.c +4 -2
  87. data/vendor/libgit2/src/libgit2/blob.h +2 -2
  88. data/vendor/libgit2/src/libgit2/branch.c +2 -2
  89. data/vendor/libgit2/src/libgit2/cherrypick.c +3 -3
  90. data/vendor/libgit2/src/libgit2/clone.c +34 -3
  91. data/vendor/libgit2/src/libgit2/commit.c +78 -21
  92. data/vendor/libgit2/src/libgit2/commit.h +25 -7
  93. data/vendor/libgit2/src/libgit2/commit_graph.c +129 -47
  94. data/vendor/libgit2/src/libgit2/commit_graph.h +23 -4
  95. data/vendor/libgit2/src/libgit2/commit_list.c +16 -5
  96. data/vendor/libgit2/src/libgit2/commit_list.h +1 -0
  97. data/vendor/libgit2/src/libgit2/config.c +6 -3
  98. data/vendor/libgit2/src/libgit2/config_file.c +16 -10
  99. data/vendor/libgit2/src/libgit2/describe.c +11 -8
  100. data/vendor/libgit2/src/libgit2/diff.c +19 -6
  101. data/vendor/libgit2/src/libgit2/diff.h +6 -6
  102. data/vendor/libgit2/src/libgit2/diff_file.c +16 -7
  103. data/vendor/libgit2/src/libgit2/diff_generate.c +37 -11
  104. data/vendor/libgit2/src/libgit2/diff_parse.c +20 -4
  105. data/vendor/libgit2/src/libgit2/diff_print.c +26 -7
  106. data/vendor/libgit2/src/libgit2/diff_tform.c +4 -0
  107. data/vendor/libgit2/src/libgit2/diff_xdiff.h +1 -1
  108. data/vendor/libgit2/src/libgit2/email.c +4 -3
  109. data/vendor/libgit2/src/libgit2/errors.c +73 -18
  110. data/vendor/libgit2/src/libgit2/experimental.h.in +13 -0
  111. data/vendor/libgit2/src/libgit2/fetch.c +38 -13
  112. data/vendor/libgit2/src/libgit2/fetch.h +0 -2
  113. data/vendor/libgit2/src/libgit2/fetchhead.c +11 -9
  114. data/vendor/libgit2/src/libgit2/grafts.c +272 -0
  115. data/vendor/libgit2/src/libgit2/grafts.h +36 -0
  116. data/vendor/libgit2/src/libgit2/ident.c +3 -3
  117. data/vendor/libgit2/src/libgit2/index.c +327 -123
  118. data/vendor/libgit2/src/libgit2/index.h +14 -1
  119. data/vendor/libgit2/src/libgit2/indexer.c +116 -46
  120. data/vendor/libgit2/src/libgit2/iterator.c +21 -4
  121. data/vendor/libgit2/src/libgit2/iterator.h +3 -0
  122. data/vendor/libgit2/src/libgit2/libgit2.c +58 -0
  123. data/vendor/libgit2/src/libgit2/merge.c +14 -9
  124. data/vendor/libgit2/src/libgit2/merge_file.c +0 -2
  125. data/vendor/libgit2/src/libgit2/midx.c +68 -38
  126. data/vendor/libgit2/src/libgit2/midx.h +13 -3
  127. data/vendor/libgit2/src/libgit2/mwindow.c +5 -2
  128. data/vendor/libgit2/src/libgit2/mwindow.h +4 -1
  129. data/vendor/libgit2/src/libgit2/notes.c +9 -8
  130. data/vendor/libgit2/src/libgit2/object.c +118 -29
  131. data/vendor/libgit2/src/libgit2/object.h +17 -2
  132. data/vendor/libgit2/src/libgit2/odb.c +224 -55
  133. data/vendor/libgit2/src/libgit2/odb.h +43 -4
  134. data/vendor/libgit2/src/libgit2/odb_loose.c +128 -70
  135. data/vendor/libgit2/src/libgit2/odb_pack.c +111 -46
  136. data/vendor/libgit2/src/libgit2/oid.c +141 -77
  137. data/vendor/libgit2/src/libgit2/oid.h +183 -9
  138. data/vendor/libgit2/src/libgit2/oidarray.c +49 -3
  139. data/vendor/libgit2/src/libgit2/oidarray.h +5 -1
  140. data/vendor/libgit2/src/libgit2/pack-objects.c +31 -13
  141. data/vendor/libgit2/src/libgit2/pack-objects.h +5 -2
  142. data/vendor/libgit2/src/libgit2/pack.c +93 -70
  143. data/vendor/libgit2/src/libgit2/pack.h +29 -15
  144. data/vendor/libgit2/src/libgit2/parse.c +8 -4
  145. data/vendor/libgit2/src/libgit2/parse.h +1 -1
  146. data/vendor/libgit2/src/libgit2/patch.h +7 -1
  147. data/vendor/libgit2/src/libgit2/patch_generate.c +24 -5
  148. data/vendor/libgit2/src/libgit2/patch_parse.c +16 -8
  149. data/vendor/libgit2/src/libgit2/push.c +13 -3
  150. data/vendor/libgit2/src/libgit2/reader.c +1 -1
  151. data/vendor/libgit2/src/libgit2/rebase.c +72 -83
  152. data/vendor/libgit2/src/libgit2/refdb_fs.c +92 -52
  153. data/vendor/libgit2/src/libgit2/reflog.c +7 -5
  154. data/vendor/libgit2/src/libgit2/reflog.h +1 -2
  155. data/vendor/libgit2/src/libgit2/refs.c +9 -0
  156. data/vendor/libgit2/src/libgit2/remote.c +47 -37
  157. data/vendor/libgit2/src/libgit2/remote.h +41 -0
  158. data/vendor/libgit2/src/libgit2/repository.c +784 -329
  159. data/vendor/libgit2/src/libgit2/repository.h +26 -2
  160. data/vendor/libgit2/src/libgit2/reset.c +2 -2
  161. data/vendor/libgit2/src/libgit2/revert.c +8 -11
  162. data/vendor/libgit2/src/libgit2/revparse.c +23 -7
  163. data/vendor/libgit2/src/libgit2/revwalk.c +31 -5
  164. data/vendor/libgit2/src/libgit2/stash.c +209 -33
  165. data/vendor/libgit2/src/libgit2/strarray.c +1 -0
  166. data/vendor/libgit2/src/libgit2/strarray.h +25 -0
  167. data/vendor/libgit2/src/libgit2/streams/mbedtls.c +0 -1
  168. data/vendor/libgit2/src/libgit2/streams/openssl.c +9 -17
  169. data/vendor/libgit2/src/libgit2/streams/openssl_dynamic.c +7 -3
  170. data/vendor/libgit2/src/libgit2/streams/schannel.c +715 -0
  171. data/vendor/libgit2/src/libgit2/streams/schannel.h +28 -0
  172. data/vendor/libgit2/src/libgit2/streams/socket.c +240 -51
  173. data/vendor/libgit2/src/libgit2/streams/socket.h +3 -1
  174. data/vendor/libgit2/src/libgit2/streams/stransport.c +40 -12
  175. data/vendor/libgit2/src/libgit2/streams/tls.c +5 -0
  176. data/vendor/libgit2/src/libgit2/submodule.c +6 -2
  177. data/vendor/libgit2/src/libgit2/submodule.h +3 -3
  178. data/vendor/libgit2/src/libgit2/sysdir.c +294 -7
  179. data/vendor/libgit2/src/libgit2/sysdir.h +41 -9
  180. data/vendor/libgit2/src/libgit2/tag.c +29 -10
  181. data/vendor/libgit2/src/libgit2/tag.h +2 -2
  182. data/vendor/libgit2/src/libgit2/threadstate.c +15 -2
  183. data/vendor/libgit2/src/libgit2/threadstate.h +1 -3
  184. data/vendor/libgit2/src/libgit2/transports/auth.h +1 -2
  185. data/vendor/libgit2/src/libgit2/transports/{auth_negotiate.c → auth_gssapi.c} +32 -32
  186. data/vendor/libgit2/src/libgit2/transports/auth_negotiate.h +1 -1
  187. data/vendor/libgit2/src/libgit2/transports/auth_ntlm.h +1 -1
  188. data/vendor/libgit2/src/libgit2/transports/{auth_ntlm.c → auth_ntlmclient.c} +12 -12
  189. data/vendor/libgit2/src/libgit2/transports/auth_sspi.c +341 -0
  190. data/vendor/libgit2/src/libgit2/transports/git.c +7 -8
  191. data/vendor/libgit2/src/libgit2/transports/http.c +15 -9
  192. data/vendor/libgit2/src/libgit2/transports/httpclient.c +14 -0
  193. data/vendor/libgit2/src/libgit2/transports/httpclient.h +10 -0
  194. data/vendor/libgit2/src/libgit2/transports/local.c +27 -4
  195. data/vendor/libgit2/src/libgit2/transports/smart.c +68 -27
  196. data/vendor/libgit2/src/libgit2/transports/smart.h +33 -9
  197. data/vendor/libgit2/src/libgit2/transports/smart_pkt.c +281 -49
  198. data/vendor/libgit2/src/libgit2/transports/smart_protocol.c +192 -55
  199. data/vendor/libgit2/src/libgit2/transports/ssh.c +334 -102
  200. data/vendor/libgit2/src/libgit2/transports/winhttp.c +22 -18
  201. data/vendor/libgit2/src/libgit2/tree-cache.c +26 -16
  202. data/vendor/libgit2/src/libgit2/tree-cache.h +5 -3
  203. data/vendor/libgit2/src/libgit2/tree.c +23 -17
  204. data/vendor/libgit2/src/libgit2/tree.h +2 -2
  205. data/vendor/libgit2/src/libgit2/worktree.c +30 -10
  206. data/vendor/libgit2/src/util/CMakeLists.txt +6 -1
  207. data/vendor/libgit2/src/util/alloc.c +65 -6
  208. data/vendor/libgit2/src/util/alloc.h +34 -9
  209. data/vendor/libgit2/src/util/allocators/failalloc.c +0 -60
  210. data/vendor/libgit2/src/util/allocators/failalloc.h +0 -6
  211. data/vendor/libgit2/src/util/allocators/stdalloc.c +2 -105
  212. data/vendor/libgit2/src/util/allocators/win32_leakcheck.c +0 -68
  213. data/vendor/libgit2/src/util/array.h +6 -1
  214. data/vendor/libgit2/src/util/cc-compat.h +2 -0
  215. data/vendor/libgit2/src/util/filebuf.c +6 -1
  216. data/vendor/libgit2/src/util/filebuf.h +19 -6
  217. data/vendor/libgit2/src/util/fs_path.c +2 -2
  218. data/vendor/libgit2/src/util/futils.c +8 -8
  219. data/vendor/libgit2/src/{features.h.in → util/git2_features.h.in} +9 -3
  220. data/vendor/libgit2/src/util/git2_util.h +2 -2
  221. data/vendor/libgit2/src/util/hash/openssl.c +4 -3
  222. data/vendor/libgit2/src/util/hash/rfc6234/sha.h +0 -112
  223. data/vendor/libgit2/src/util/hash.h +13 -0
  224. data/vendor/libgit2/src/util/net.c +492 -87
  225. data/vendor/libgit2/src/util/net.h +32 -0
  226. data/vendor/libgit2/src/util/posix.c +54 -0
  227. data/vendor/libgit2/src/util/posix.h +24 -0
  228. data/vendor/libgit2/src/util/rand.c +10 -4
  229. data/vendor/libgit2/src/util/regexp.c +3 -3
  230. data/vendor/libgit2/src/util/staticstr.h +66 -0
  231. data/vendor/libgit2/src/util/thread.h +20 -19
  232. data/vendor/libgit2/src/util/util.c +15 -10
  233. data/vendor/libgit2/src/util/util.h +25 -16
  234. data/vendor/libgit2/src/util/win32/error.c +1 -1
  235. data/vendor/libgit2/src/util/win32/path_w32.c +8 -8
  236. data/vendor/libgit2/src/util/win32/posix_w32.c +1 -1
  237. data/vendor/libgit2/src/util/win32/utf-conv.c +73 -75
  238. data/vendor/libgit2/src/util/win32/utf-conv.h +81 -14
  239. data/vendor/libgit2/src/util/win32/w32_util.c +1 -1
  240. metadata +34 -26
  241. data/vendor/libgit2/cmake/SelectWinHTTP.cmake +0 -17
  242. data/vendor/libgit2/src/libgit2/netops.c +0 -124
  243. data/vendor/libgit2/src/libgit2/netops.h +0 -68
  244. data/vendor/libgit2/src/util/win32/findfile.c +0 -286
  245. data/vendor/libgit2/src/util/win32/findfile.h +0 -22
  246. /data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xdiff.h +0 -0
  247. /data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xemit.h +0 -0
  248. /data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xinclude.h +0 -0
  249. /data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xprepare.h +0 -0
  250. /data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xtypes.h +0 -0
@@ -114,23 +114,16 @@ static int midx_parse_oid_lookup(
114
114
  const unsigned char *data,
115
115
  struct git_midx_chunk *chunk_oid_lookup)
116
116
  {
117
- uint32_t i;
118
- unsigned char *oid, *prev_oid, zero_oid[GIT_OID_RAWSZ] = {0};
117
+ size_t oid_size = git_oid_size(idx->oid_type);
119
118
 
120
119
  if (chunk_oid_lookup->offset == 0)
121
120
  return midx_error("missing OID Lookup chunk");
122
121
  if (chunk_oid_lookup->length == 0)
123
122
  return midx_error("empty OID Lookup chunk");
124
- if (chunk_oid_lookup->length != idx->num_objects * GIT_OID_RAWSZ)
123
+ if (chunk_oid_lookup->length != idx->num_objects * oid_size)
125
124
  return midx_error("OID Lookup chunk has wrong length");
126
125
 
127
- idx->oid_lookup = oid = (unsigned char *)(data + chunk_oid_lookup->offset);
128
- prev_oid = zero_oid;
129
- for (i = 0; i < idx->num_objects; ++i, oid += GIT_OID_RAWSZ) {
130
- if (git_oid_raw_cmp(prev_oid, oid) >= 0)
131
- return midx_error("OID Lookup index is non-monotonic");
132
- prev_oid = oid;
133
- }
126
+ idx->oid_lookup = (unsigned char *)(data + chunk_oid_lookup->offset);
134
127
 
135
128
  return 0;
136
129
  }
@@ -178,17 +171,20 @@ int git_midx_parse(
178
171
  struct git_midx_chunk *last_chunk;
179
172
  uint32_t i;
180
173
  off64_t last_chunk_offset, chunk_offset, trailer_offset;
181
- size_t checksum_size;
174
+ size_t checksum_size, oid_size;
182
175
  int error;
183
176
  struct git_midx_chunk chunk_packfile_names = {0},
184
177
  chunk_oid_fanout = {0},
185
178
  chunk_oid_lookup = {0},
186
179
  chunk_object_offsets = {0},
187
- chunk_object_large_offsets = {0};
180
+ chunk_object_large_offsets = {0},
181
+ chunk_unknown = {0};
188
182
 
189
183
  GIT_ASSERT_ARG(idx);
190
184
 
191
- if (size < sizeof(struct git_midx_header) + GIT_OID_RAWSZ)
185
+ oid_size = git_oid_size(idx->oid_type);
186
+
187
+ if (size < sizeof(struct git_midx_header) + oid_size)
192
188
  return midx_error("multi-pack index is too short");
193
189
 
194
190
  hdr = ((struct git_midx_header *)data);
@@ -209,7 +205,7 @@ int git_midx_parse(
209
205
  sizeof(struct git_midx_header) +
210
206
  (1 + hdr->chunks) * 12;
211
207
 
212
- checksum_size = GIT_HASH_SHA1_SIZE;
208
+ checksum_size = oid_size;
213
209
  trailer_offset = size - checksum_size;
214
210
 
215
211
  if (trailer_offset < last_chunk_offset)
@@ -261,7 +257,9 @@ int git_midx_parse(
261
257
  break;
262
258
 
263
259
  default:
264
- return midx_error("unrecognized chunk ID");
260
+ chunk_unknown.offset = last_chunk_offset;
261
+ last_chunk = &chunk_unknown;
262
+ break;
265
263
  }
266
264
  }
267
265
  last_chunk->length = (size_t)(trailer_offset - last_chunk_offset);
@@ -287,8 +285,9 @@ int git_midx_parse(
287
285
  }
288
286
 
289
287
  int git_midx_open(
290
- git_midx_file **idx_out,
291
- const char *path)
288
+ git_midx_file **idx_out,
289
+ const char *path,
290
+ git_oid_t oid_type)
292
291
  {
293
292
  git_midx_file *idx;
294
293
  git_file fd = -1;
@@ -296,6 +295,8 @@ int git_midx_open(
296
295
  struct stat st;
297
296
  int error;
298
297
 
298
+ GIT_ASSERT_ARG(idx_out && path && oid_type);
299
+
299
300
  /* TODO: properly open the file without access time using O_NOATIME */
300
301
  fd = git_futils_open_ro(path);
301
302
  if (fd < 0)
@@ -317,6 +318,8 @@ int git_midx_open(
317
318
  idx = git__calloc(1, sizeof(git_midx_file));
318
319
  GIT_ERROR_CHECK_ALLOC(idx);
319
320
 
321
+ idx->oid_type = oid_type;
322
+
320
323
  error = git_str_sets(&idx->filename, path);
321
324
  if (error < 0)
322
325
  return error;
@@ -344,7 +347,7 @@ bool git_midx_needs_refresh(
344
347
  git_file fd = -1;
345
348
  struct stat st;
346
349
  ssize_t bytes_read;
347
- unsigned char checksum[GIT_HASH_SHA1_SIZE];
350
+ unsigned char checksum[GIT_HASH_MAX_SIZE];
348
351
  size_t checksum_size;
349
352
 
350
353
  /* TODO: properly open the file without access time using O_NOATIME */
@@ -364,8 +367,8 @@ bool git_midx_needs_refresh(
364
367
  return true;
365
368
  }
366
369
 
367
- checksum_size = GIT_HASH_SHA1_SIZE;
368
- bytes_read = p_pread(fd, checksum, checksum_size, st.st_size - GIT_OID_RAWSZ);
370
+ checksum_size = git_oid_size(idx->oid_type);
371
+ bytes_read = p_pread(fd, checksum, checksum_size, st.st_size - checksum_size);
369
372
  p_close(fd);
370
373
 
371
374
  if (bytes_read != (ssize_t)checksum_size)
@@ -381,7 +384,7 @@ int git_midx_entry_find(
381
384
  size_t len)
382
385
  {
383
386
  int pos, found = 0;
384
- size_t pack_index;
387
+ size_t pack_index, oid_size, oid_hexsize;
385
388
  uint32_t hi, lo;
386
389
  unsigned char *current = NULL;
387
390
  const unsigned char *object_offset;
@@ -389,30 +392,33 @@ int git_midx_entry_find(
389
392
 
390
393
  GIT_ASSERT_ARG(idx);
391
394
 
395
+ oid_size = git_oid_size(idx->oid_type);
396
+ oid_hexsize = git_oid_hexsize(idx->oid_type);
397
+
392
398
  hi = ntohl(idx->oid_fanout[(int)short_oid->id[0]]);
393
399
  lo = ((short_oid->id[0] == 0x0) ? 0 : ntohl(idx->oid_fanout[(int)short_oid->id[0] - 1]));
394
400
 
395
- pos = git_pack__lookup_sha1(idx->oid_lookup, GIT_OID_RAWSZ, lo, hi, short_oid->id);
401
+ pos = git_pack__lookup_id(idx->oid_lookup, oid_size, lo, hi, short_oid->id, idx->oid_type);
396
402
 
397
403
  if (pos >= 0) {
398
404
  /* An object matching exactly the oid was found */
399
405
  found = 1;
400
- current = idx->oid_lookup + (pos * GIT_OID_RAWSZ);
406
+ current = idx->oid_lookup + (pos * oid_size);
401
407
  } else {
402
408
  /* No object was found */
403
409
  /* pos refers to the object with the "closest" oid to short_oid */
404
410
  pos = -1 - pos;
405
411
  if (pos < (int)idx->num_objects) {
406
- current = idx->oid_lookup + (pos * GIT_OID_RAWSZ);
412
+ current = idx->oid_lookup + (pos * oid_size);
407
413
 
408
414
  if (!git_oid_raw_ncmp(short_oid->id, current, len))
409
415
  found = 1;
410
416
  }
411
417
  }
412
418
 
413
- if (found && len != GIT_OID_HEXSZ && pos + 1 < (int)idx->num_objects) {
419
+ if (found && len != oid_hexsize && pos + 1 < (int)idx->num_objects) {
414
420
  /* Check for ambiguousity */
415
- const unsigned char *next = current + GIT_OID_RAWSZ;
421
+ const unsigned char *next = current + oid_size;
416
422
 
417
423
  if (!git_oid_raw_ncmp(short_oid->id, next, len))
418
424
  found = 2;
@@ -443,7 +449,7 @@ int git_midx_entry_find(
443
449
  return midx_error("invalid index into the packfile names table");
444
450
  e->pack_index = pack_index;
445
451
  e->offset = offset;
446
- git_oid_fromraw(&e->sha1, current);
452
+ git_oid__fromraw(&e->sha1, current, idx->oid_type);
447
453
  return 0;
448
454
  }
449
455
 
@@ -453,13 +459,15 @@ int git_midx_foreach_entry(
453
459
  void *data)
454
460
  {
455
461
  git_oid oid;
456
- size_t i;
462
+ size_t oid_size, i;
457
463
  int error;
458
464
 
459
465
  GIT_ASSERT_ARG(idx);
460
466
 
467
+ oid_size = git_oid_size(idx->oid_type);
468
+
461
469
  for (i = 0; i < idx->num_objects; ++i) {
462
- if ((error = git_oid_fromraw(&oid, &idx->oid_lookup[i * GIT_OID_RAWSZ])) < 0)
470
+ if ((error = git_oid__fromraw(&oid, &idx->oid_lookup[i * oid_size], idx->oid_type)) < 0)
463
471
  return error;
464
472
 
465
473
  if ((error = cb(&oid, data)) != 0)
@@ -501,9 +509,21 @@ static int packfile__cmp(const void *a_, const void *b_)
501
509
 
502
510
  int git_midx_writer_new(
503
511
  git_midx_writer **out,
504
- const char *pack_dir)
512
+ const char *pack_dir
513
+ #ifdef GIT_EXPERIMENTAL_SHA256
514
+ , git_oid_t oid_type
515
+ #endif
516
+ )
505
517
  {
506
- git_midx_writer *w = git__calloc(1, sizeof(git_midx_writer));
518
+ git_midx_writer *w;
519
+
520
+ #ifndef GIT_EXPERIMENTAL_SHA256
521
+ git_oid_t oid_type = GIT_OID_SHA1;
522
+ #endif
523
+
524
+ GIT_ASSERT_ARG(out && pack_dir && oid_type);
525
+
526
+ w = git__calloc(1, sizeof(git_midx_writer));
507
527
  GIT_ERROR_CHECK_ALLOC(w);
508
528
 
509
529
  if (git_str_sets(&w->pack_dir, pack_dir) < 0) {
@@ -518,6 +538,8 @@ int git_midx_writer_new(
518
538
  return -1;
519
539
  }
520
540
 
541
+ w->oid_type = oid_type;
542
+
521
543
  *out = w;
522
544
  return 0;
523
545
  }
@@ -549,7 +571,8 @@ int git_midx_writer_add(
549
571
  if (error < 0)
550
572
  return error;
551
573
 
552
- error = git_mwindow_get_pack(&p, git_str_cstr(&idx_path_buf));
574
+ /* TODO: SHA256 */
575
+ error = git_mwindow_get_pack(&p, git_str_cstr(&idx_path_buf), 0);
553
576
  git_str_dispose(&idx_path_buf);
554
577
  if (error < 0)
555
578
  return error;
@@ -661,12 +684,13 @@ static int midx_write(
661
684
  oid_lookup = GIT_STR_INIT,
662
685
  object_offsets = GIT_STR_INIT,
663
686
  object_large_offsets = GIT_STR_INIT;
664
- unsigned char checksum[GIT_HASH_SHA1_SIZE];
665
- size_t checksum_size;
687
+ unsigned char checksum[GIT_HASH_MAX_SIZE];
688
+ size_t checksum_size, oid_size;
666
689
  git_midx_entry *entry;
667
690
  object_entry_array_t object_entries_array = GIT_ARRAY_INIT;
668
691
  git_vector object_entries = GIT_VECTOR_INIT;
669
692
  git_hash_ctx ctx;
693
+ git_hash_algorithm_t checksum_type;
670
694
  struct midx_write_hash_context hash_cb_data = {0};
671
695
 
672
696
  hdr.signature = htonl(MIDX_SIGNATURE);
@@ -678,10 +702,14 @@ static int midx_write(
678
702
  hash_cb_data.cb_data = cb_data;
679
703
  hash_cb_data.ctx = &ctx;
680
704
 
681
- checksum_size = GIT_HASH_SHA1_SIZE;
682
- error = git_hash_ctx_init(&ctx, GIT_HASH_ALGORITHM_SHA1);
683
- if (error < 0)
705
+ oid_size = git_oid_size(w->oid_type);
706
+
707
+ GIT_ASSERT((checksum_type = git_oid_algorithm(w->oid_type)));
708
+ checksum_size = git_hash_size(checksum_type);
709
+
710
+ if ((error = git_hash_ctx_init(&ctx, checksum_type)) < 0)
684
711
  return error;
712
+
685
713
  cb_data = &hash_cb_data;
686
714
  write_cb = midx_write_hash;
687
715
 
@@ -748,7 +776,9 @@ static int midx_write(
748
776
 
749
777
  /* Fill the OID Lookup table. */
750
778
  git_vector_foreach (&object_entries, i, entry) {
751
- error = git_str_put(&oid_lookup, (char *)&entry->sha1.id, GIT_OID_RAWSZ);
779
+ error = git_str_put(&oid_lookup,
780
+ (char *)&entry->sha1.id, oid_size);
781
+
752
782
  if (error < 0)
753
783
  goto cleanup;
754
784
  }
@@ -51,8 +51,14 @@ typedef struct git_midx_file {
51
51
  /* The number of entries in the Object Large Offsets table. Each entry has an 8-byte with an offset */
52
52
  size_t num_object_large_offsets;
53
53
 
54
- /* The trailer of the file. Contains the SHA1-checksum of the whole file. */
55
- unsigned char checksum[GIT_HASH_SHA1_SIZE];
54
+ /*
55
+ * The trailer of the file. Contains the checksum of the whole
56
+ * file, in the repository's object format hash.
57
+ */
58
+ unsigned char checksum[GIT_HASH_MAX_SIZE];
59
+
60
+ /* The type of object IDs in the midx. */
61
+ git_oid_t oid_type;
56
62
 
57
63
  /* something like ".git/objects/pack/multi-pack-index". */
58
64
  git_str filename;
@@ -82,11 +88,15 @@ struct git_midx_writer {
82
88
 
83
89
  /* The list of `git_pack_file`s. */
84
90
  git_vector packs;
91
+
92
+ /* The object ID type of the writer. */
93
+ git_oid_t oid_type;
85
94
  };
86
95
 
87
96
  int git_midx_open(
88
97
  git_midx_file **idx_out,
89
- const char *path);
98
+ const char *path,
99
+ git_oid_t oid_type);
90
100
  bool git_midx_needs_refresh(
91
101
  const git_midx_file *idx,
92
102
  const char *path);
@@ -61,7 +61,10 @@ int git_mwindow_global_init(void)
61
61
  return git_runtime_shutdown_register(git_mwindow_global_shutdown);
62
62
  }
63
63
 
64
- int git_mwindow_get_pack(struct git_pack_file **out, const char *path)
64
+ int git_mwindow_get_pack(
65
+ struct git_pack_file **out,
66
+ const char *path,
67
+ git_oid_t oid_type)
65
68
  {
66
69
  struct git_pack_file *pack;
67
70
  char *packname;
@@ -86,7 +89,7 @@ int git_mwindow_get_pack(struct git_pack_file **out, const char *path)
86
89
  }
87
90
 
88
91
  /* If we didn't find it, we need to create it */
89
- if ((error = git_packfile_alloc(&pack, path)) < 0) {
92
+ if ((error = git_packfile_alloc(&pack, path, oid_type)) < 0) {
90
93
  git_mutex_unlock(&git__mwindow_mutex);
91
94
  return error;
92
95
  }
@@ -48,7 +48,10 @@ void git_mwindow_close(git_mwindow **w_cursor);
48
48
  extern int git_mwindow_global_init(void);
49
49
 
50
50
  struct git_pack_file; /* just declaration to avoid cyclical includes */
51
- int git_mwindow_get_pack(struct git_pack_file **out, const char *path);
51
+ int git_mwindow_get_pack(
52
+ struct git_pack_file **out,
53
+ const char *path,
54
+ git_oid_t oid_type);
52
55
  int git_mwindow_put_pack(struct git_pack_file *pack);
53
56
 
54
57
  #endif
@@ -460,7 +460,7 @@ int git_note_commit_read(
460
460
  {
461
461
  int error;
462
462
  git_tree *tree = NULL;
463
- char target[GIT_OID_HEXSZ + 1];
463
+ char target[GIT_OID_MAX_HEXSIZE + 1];
464
464
 
465
465
  git_oid_tostr(target, sizeof(target), oid);
466
466
 
@@ -507,7 +507,7 @@ int git_note_commit_create(
507
507
  {
508
508
  int error;
509
509
  git_tree *tree = NULL;
510
- char target[GIT_OID_HEXSZ + 1];
510
+ char target[GIT_OID_MAX_HEXSIZE + 1];
511
511
 
512
512
  git_oid_tostr(target, sizeof(target), oid);
513
513
 
@@ -578,7 +578,7 @@ int git_note_commit_remove(
578
578
  {
579
579
  int error;
580
580
  git_tree *tree = NULL;
581
- char target[GIT_OID_HEXSZ + 1];
581
+ char target[GIT_OID_MAX_HEXSIZE + 1];
582
582
 
583
583
  git_oid_tostr(target, sizeof(target), oid);
584
584
 
@@ -665,8 +665,9 @@ void git_note_free(git_note *note)
665
665
  }
666
666
 
667
667
  static int process_entry_path(
668
- const char *entry_path,
669
- git_oid *annotated_object_id)
668
+ git_oid *annotated_object_id,
669
+ git_note_iterator *it,
670
+ const char *entry_path)
670
671
  {
671
672
  int error = 0;
672
673
  size_t i = 0, j = 0, len;
@@ -698,12 +699,12 @@ static int process_entry_path(
698
699
  buf.ptr[j] = '\0';
699
700
  buf.size = j;
700
701
 
701
- if (j != GIT_OID_HEXSZ) {
702
+ if (j != git_oid_hexsize(it->repo->oid_type)) {
702
703
  /* This is not a note entry */
703
704
  goto cleanup;
704
705
  }
705
706
 
706
- error = git_oid_fromstr(annotated_object_id, buf.ptr);
707
+ error = git_oid__fromstr(annotated_object_id, buf.ptr, it->repo->oid_type);
707
708
 
708
709
  cleanup:
709
710
  git_str_dispose(&buf);
@@ -799,7 +800,7 @@ int git_note_next(
799
800
 
800
801
  git_oid_cpy(note_id, &item->id);
801
802
 
802
- if ((error = process_entry_path(item->path, annotated_id)) < 0)
803
+ if ((error = process_entry_path(annotated_id, it, item->path)) < 0)
803
804
  return error;
804
805
 
805
806
  if ((error = git_iterator_advance(NULL, it)) < 0 && error != GIT_ITEROVER)
@@ -21,15 +21,14 @@
21
21
 
22
22
  bool git_object__strict_input_validation = true;
23
23
 
24
- extern int git_odb_hash(git_oid *out, const void *data, size_t len, git_object_t type);
25
24
  size_t git_object__size(git_object_t type);
26
25
 
27
26
  typedef struct {
28
27
  const char *str; /* type name string */
29
28
  size_t size; /* size in bytes of the object structure */
30
29
 
31
- int (*parse)(void *self, git_odb_object *obj);
32
- int (*parse_raw)(void *self, const char *data, size_t size);
30
+ int (*parse)(void *self, git_odb_object *obj, git_oid_t oid_type);
31
+ int (*parse_raw)(void *self, const char *data, size_t size, git_oid_t oid_type);
33
32
  void (*free)(void *self);
34
33
  } git_object_def;
35
34
 
@@ -61,7 +60,8 @@ int git_object__from_raw(
61
60
  git_object **object_out,
62
61
  const char *data,
63
62
  size_t size,
64
- git_object_t type)
63
+ git_object_t object_type,
64
+ git_oid_t oid_type)
65
65
  {
66
66
  git_object_def *def;
67
67
  git_object *object;
@@ -72,12 +72,15 @@ int git_object__from_raw(
72
72
  *object_out = NULL;
73
73
 
74
74
  /* Validate type match */
75
- if (type != GIT_OBJECT_BLOB && type != GIT_OBJECT_TREE && type != GIT_OBJECT_COMMIT && type != GIT_OBJECT_TAG) {
75
+ if (object_type != GIT_OBJECT_BLOB &&
76
+ object_type != GIT_OBJECT_TREE &&
77
+ object_type != GIT_OBJECT_COMMIT &&
78
+ object_type != GIT_OBJECT_TAG) {
76
79
  git_error_set(GIT_ERROR_INVALID, "the requested type is invalid");
77
80
  return GIT_ENOTFOUND;
78
81
  }
79
82
 
80
- if ((object_size = git_object__size(type)) == 0) {
83
+ if ((object_size = git_object__size(object_type)) == 0) {
81
84
  git_error_set(GIT_ERROR_INVALID, "the requested type is invalid");
82
85
  return GIT_ENOTFOUND;
83
86
  }
@@ -86,15 +89,15 @@ int git_object__from_raw(
86
89
  object = git__calloc(1, object_size);
87
90
  GIT_ERROR_CHECK_ALLOC(object);
88
91
  object->cached.flags = GIT_CACHE_STORE_PARSED;
89
- object->cached.type = type;
90
- if ((error = git_odb_hash(&object->cached.oid, data, size, type)) < 0)
92
+ object->cached.type = object_type;
93
+ if ((error = git_odb__hash(&object->cached.oid, data, size, object_type, oid_type)) < 0)
91
94
  return error;
92
95
 
93
96
  /* Parse raw object data */
94
- def = &git_objects_table[type];
97
+ def = &git_objects_table[object_type];
95
98
  GIT_ASSERT(def->free && def->parse_raw);
96
99
 
97
- if ((error = def->parse_raw(object, data, size)) < 0) {
100
+ if ((error = def->parse_raw(object, data, size, oid_type)) < 0) {
98
101
  def->free(object);
99
102
  return error;
100
103
  }
@@ -105,15 +108,13 @@ int git_object__from_raw(
105
108
  return 0;
106
109
  }
107
110
 
108
- int git_object__from_odb_object(
111
+ int git_object__init_from_odb_object(
109
112
  git_object **object_out,
110
113
  git_repository *repo,
111
114
  git_odb_object *odb_obj,
112
115
  git_object_t type)
113
116
  {
114
- int error;
115
117
  size_t object_size;
116
- git_object_def *def;
117
118
  git_object *object = NULL;
118
119
 
119
120
  GIT_ASSERT_ARG(object_out);
@@ -140,11 +141,28 @@ int git_object__from_odb_object(
140
141
  object->cached.size = odb_obj->cached.size;
141
142
  object->repo = repo;
142
143
 
144
+ *object_out = object;
145
+ return 0;
146
+ }
147
+
148
+ int git_object__from_odb_object(
149
+ git_object **object_out,
150
+ git_repository *repo,
151
+ git_odb_object *odb_obj,
152
+ git_object_t type)
153
+ {
154
+ int error;
155
+ git_object_def *def;
156
+ git_object *object = NULL;
157
+
158
+ if ((error = git_object__init_from_odb_object(&object, repo, odb_obj, type)) < 0)
159
+ return error;
160
+
143
161
  /* Parse raw object data */
144
162
  def = &git_objects_table[odb_obj->cached.type];
145
163
  GIT_ASSERT(def->free && def->parse);
146
164
 
147
- if ((error = def->parse(object, odb_obj)) < 0) {
165
+ if ((error = def->parse(object, odb_obj, repo->oid_type)) < 0) {
148
166
  /*
149
167
  * parse returns EINVALID on invalid data; downgrade
150
168
  * that to a normal -1 error code.
@@ -178,6 +196,7 @@ int git_object_lookup_prefix(
178
196
  git_object *object = NULL;
179
197
  git_odb *odb = NULL;
180
198
  git_odb_object *odb_obj = NULL;
199
+ size_t oid_hexsize;
181
200
  int error = 0;
182
201
 
183
202
  GIT_ASSERT_ARG(repo);
@@ -193,10 +212,12 @@ int git_object_lookup_prefix(
193
212
  if (error < 0)
194
213
  return error;
195
214
 
196
- if (len > GIT_OID_HEXSZ)
197
- len = GIT_OID_HEXSZ;
215
+ oid_hexsize = git_oid_hexsize(repo->oid_type);
216
+
217
+ if (len > oid_hexsize)
218
+ len = oid_hexsize;
198
219
 
199
- if (len == GIT_OID_HEXSZ) {
220
+ if (len == oid_hexsize) {
200
221
  git_cached_obj *cached = NULL;
201
222
 
202
223
  /* We want to match the full id : we can first look up in the cache,
@@ -230,11 +251,12 @@ int git_object_lookup_prefix(
230
251
  error = git_odb_read(&odb_obj, odb, id);
231
252
  }
232
253
  } else {
233
- git_oid short_oid = {{ 0 }};
254
+ git_oid short_oid;
234
255
 
256
+ git_oid_clear(&short_oid, repo->oid_type);
235
257
  git_oid__cpy_prefix(&short_oid, id, len);
236
258
 
237
- /* If len < GIT_OID_HEXSZ (a strict short oid was given), we have
259
+ /* If len < GIT_OID_SHA1_HEXSIZE (a strict short oid was given), we have
238
260
  * 2 options :
239
261
  * - We always search in the cache first. If we find that short oid is
240
262
  * ambiguous, we can stop. But in all the other cases, we must then
@@ -259,7 +281,8 @@ int git_object_lookup_prefix(
259
281
  }
260
282
 
261
283
  int git_object_lookup(git_object **object_out, git_repository *repo, const git_oid *id, git_object_t type) {
262
- return git_object_lookup_prefix(object_out, repo, id, GIT_OID_HEXSZ, type);
284
+ return git_object_lookup_prefix(object_out,
285
+ repo, id, git_oid_hexsize(repo->oid_type), type);
263
286
  }
264
287
 
265
288
  void git_object_free(git_object *object)
@@ -358,12 +381,11 @@ static int dereference_object(git_object **dereferenced, git_object *obj)
358
381
  static int peel_error(int error, const git_oid *oid, git_object_t type)
359
382
  {
360
383
  const char *type_name;
361
- char hex_oid[GIT_OID_HEXSZ + 1];
384
+ char hex_oid[GIT_OID_MAX_HEXSIZE + 1];
362
385
 
363
386
  type_name = git_object_type2string(type);
364
387
 
365
- git_oid_fmt(hex_oid, oid);
366
- hex_oid[GIT_OID_HEXSZ] = '\0';
388
+ git_oid_nfmt(hex_oid, GIT_OID_MAX_HEXSIZE + 1, oid);
367
389
 
368
390
  git_error_set(GIT_ERROR_OBJECT, "the git_object of id '%s' can not be "
369
391
  "successfully peeled into a %s (git_object_t=%i).", hex_oid, type_name, type);
@@ -501,22 +523,31 @@ cleanup:
501
523
  static int git_object__short_id(git_str *out, const git_object *obj)
502
524
  {
503
525
  git_repository *repo;
504
- int len = GIT_ABBREV_DEFAULT, error;
505
- git_oid id = {{0}};
526
+ git_oid id;
506
527
  git_odb *odb;
528
+ size_t oid_hexsize;
529
+ int len = GIT_ABBREV_DEFAULT, error;
507
530
 
508
531
  GIT_ASSERT_ARG(out);
509
532
  GIT_ASSERT_ARG(obj);
510
533
 
511
534
  repo = git_object_owner(obj);
512
535
 
536
+ git_oid_clear(&id, repo->oid_type);
537
+ oid_hexsize = git_oid_hexsize(repo->oid_type);
538
+
513
539
  if ((error = git_repository__configmap_lookup(&len, repo, GIT_CONFIGMAP_ABBREV)) < 0)
514
540
  return error;
515
541
 
542
+ if (len < 0 || (size_t)len > oid_hexsize) {
543
+ git_error_set(GIT_ERROR_CONFIG, "invalid oid abbreviation setting: '%d'", len);
544
+ return -1;
545
+ }
546
+
516
547
  if ((error = git_repository_odb(&odb, repo)) < 0)
517
548
  return error;
518
549
 
519
- while (len < GIT_OID_HEXSZ) {
550
+ while ((size_t)len < oid_hexsize) {
520
551
  /* set up short oid */
521
552
  memcpy(&id.id, &obj->cached.oid.id, (len + 1) / 2);
522
553
  if (len & 1)
@@ -573,21 +604,29 @@ int git_object_rawcontent_is_valid(
573
604
  int *valid,
574
605
  const char *buf,
575
606
  size_t len,
576
- git_object_t type)
607
+ git_object_t object_type
608
+ #ifdef GIT_EXPERIMENTAL_SHA256
609
+ , git_oid_t oid_type
610
+ #endif
611
+ )
577
612
  {
578
613
  git_object *obj = NULL;
579
614
  int error;
580
615
 
616
+ #ifndef GIT_EXPERIMENTAL_SHA256
617
+ git_oid_t oid_type = GIT_OID_SHA1;
618
+ #endif
619
+
581
620
  GIT_ASSERT_ARG(valid);
582
621
  GIT_ASSERT_ARG(buf);
583
622
 
584
623
  /* Blobs are always valid; don't bother parsing. */
585
- if (type == GIT_OBJECT_BLOB) {
624
+ if (object_type == GIT_OBJECT_BLOB) {
586
625
  *valid = 1;
587
626
  return 0;
588
627
  }
589
628
 
590
- error = git_object__from_raw(&obj, buf, len, type);
629
+ error = git_object__from_raw(&obj, buf, len, object_type, oid_type);
591
630
  git_object_free(obj);
592
631
 
593
632
  if (error == 0) {
@@ -600,3 +639,53 @@ int git_object_rawcontent_is_valid(
600
639
 
601
640
  return error;
602
641
  }
642
+
643
+ int git_object__parse_oid_header(
644
+ git_oid *oid,
645
+ const char **buffer_out,
646
+ const char *buffer_end,
647
+ const char *header,
648
+ git_oid_t oid_type)
649
+ {
650
+ const size_t sha_len = git_oid_hexsize(oid_type);
651
+ const size_t header_len = strlen(header);
652
+
653
+ const char *buffer = *buffer_out;
654
+
655
+ if (buffer + (header_len + sha_len + 1) > buffer_end)
656
+ return -1;
657
+
658
+ if (memcmp(buffer, header, header_len) != 0)
659
+ return -1;
660
+
661
+ if (buffer[header_len + sha_len] != '\n')
662
+ return -1;
663
+
664
+ if (git_oid__fromstr(oid, buffer + header_len, oid_type) < 0)
665
+ return -1;
666
+
667
+ *buffer_out = buffer + (header_len + sha_len + 1);
668
+
669
+ return 0;
670
+ }
671
+
672
+ int git_object__write_oid_header(
673
+ git_str *buf,
674
+ const char *header,
675
+ const git_oid *oid)
676
+ {
677
+ size_t hex_size = git_oid_hexsize(git_oid_type(oid));
678
+ char hex_oid[GIT_OID_MAX_HEXSIZE];
679
+
680
+ if (!hex_size) {
681
+ git_error_set(GIT_ERROR_INVALID, "unknown type");
682
+ return -1;
683
+ }
684
+
685
+ git_oid_fmt(hex_oid, oid);
686
+ git_str_puts(buf, header);
687
+ git_str_put(buf, hex_oid, hex_size);
688
+ git_str_putc(buf, '\n');
689
+
690
+ return git_str_oom(buf) ? -1 : 0;
691
+ }