rugged 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (288) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +1 -0
  3. data/README.md +1 -1
  4. data/ext/rugged/rugged.c +7 -4
  5. data/ext/rugged/rugged_object.c +1 -1
  6. data/ext/rugged/rugged_repo.c +3 -3
  7. data/lib/rugged/repository.rb +2 -2
  8. data/lib/rugged/version.rb +1 -1
  9. data/vendor/libgit2/CMakeLists.txt +11 -6
  10. data/vendor/libgit2/COPYING +109 -1
  11. data/vendor/libgit2/cmake/Findfutimens.cmake +14 -0
  12. data/vendor/libgit2/cmake/SelectHTTPSBackend.cmake +4 -0
  13. data/vendor/libgit2/cmake/SelectHashes.cmake +1 -0
  14. data/vendor/libgit2/deps/chromium-zlib/CMakeLists.txt +101 -0
  15. data/vendor/libgit2/deps/ntlmclient/CMakeLists.txt +18 -5
  16. data/vendor/libgit2/deps/ntlmclient/compat.h +0 -34
  17. data/vendor/libgit2/deps/ntlmclient/crypt.h +14 -9
  18. data/vendor/libgit2/deps/ntlmclient/crypt_commoncrypto.c +20 -20
  19. data/vendor/libgit2/deps/ntlmclient/crypt_commoncrypto.h +3 -3
  20. data/vendor/libgit2/deps/ntlmclient/crypt_mbedtls.c +37 -36
  21. data/vendor/libgit2/deps/ntlmclient/crypt_mbedtls.h +4 -3
  22. data/vendor/libgit2/deps/ntlmclient/crypt_openssl.c +178 -51
  23. data/vendor/libgit2/deps/ntlmclient/crypt_openssl.h +74 -5
  24. data/vendor/libgit2/deps/ntlmclient/ntlm.c +156 -124
  25. data/vendor/libgit2/deps/ntlmclient/ntlm.h +13 -9
  26. data/vendor/libgit2/deps/ntlmclient/ntlmclient.h +16 -3
  27. data/vendor/libgit2/deps/ntlmclient/unicode.h +10 -4
  28. data/vendor/libgit2/deps/ntlmclient/unicode_builtin.c +16 -27
  29. data/vendor/libgit2/deps/ntlmclient/unicode_builtin.h +20 -0
  30. data/vendor/libgit2/deps/ntlmclient/unicode_iconv.c +28 -52
  31. data/vendor/libgit2/deps/ntlmclient/unicode_iconv.h +22 -0
  32. data/vendor/libgit2/deps/ntlmclient/util.c +15 -1
  33. data/vendor/libgit2/deps/ntlmclient/util.h +2 -1
  34. data/vendor/libgit2/include/git2/apply.h +2 -0
  35. data/vendor/libgit2/include/git2/attr.h +89 -0
  36. data/vendor/libgit2/include/git2/blame.h +93 -42
  37. data/vendor/libgit2/include/git2/blob.h +31 -3
  38. data/vendor/libgit2/include/git2/branch.h +25 -0
  39. data/vendor/libgit2/include/git2/cert.h +42 -5
  40. data/vendor/libgit2/include/git2/checkout.h +28 -12
  41. data/vendor/libgit2/include/git2/commit.h +35 -19
  42. data/vendor/libgit2/include/git2/common.h +19 -4
  43. data/vendor/libgit2/include/git2/config.h +1 -1
  44. data/vendor/libgit2/include/git2/deprecated.h +206 -6
  45. data/vendor/libgit2/include/git2/diff.h +35 -20
  46. data/vendor/libgit2/include/git2/errors.h +6 -6
  47. data/vendor/libgit2/include/git2/filter.h +57 -17
  48. data/vendor/libgit2/include/git2/graph.h +20 -2
  49. data/vendor/libgit2/include/git2/index.h +3 -3
  50. data/vendor/libgit2/include/git2/indexer.h +2 -1
  51. data/vendor/libgit2/include/git2/odb.h +44 -20
  52. data/vendor/libgit2/include/git2/patch.h +8 -0
  53. data/vendor/libgit2/include/git2/rebase.h +25 -1
  54. data/vendor/libgit2/include/git2/refs.h +9 -5
  55. data/vendor/libgit2/include/git2/remote.h +59 -6
  56. data/vendor/libgit2/include/git2/repository.h +95 -52
  57. data/vendor/libgit2/include/git2/revparse.h +5 -5
  58. data/vendor/libgit2/include/git2/status.h +115 -59
  59. data/vendor/libgit2/include/git2/submodule.h +9 -0
  60. data/vendor/libgit2/include/git2/sys/commit_graph.h +174 -0
  61. data/vendor/libgit2/include/git2/sys/filter.h +49 -28
  62. data/vendor/libgit2/include/git2/sys/midx.h +74 -0
  63. data/vendor/libgit2/include/git2/sys/odb_backend.h +7 -0
  64. data/vendor/libgit2/include/git2/sys/transport.h +1 -0
  65. data/vendor/libgit2/include/git2/tag.h +12 -0
  66. data/vendor/libgit2/include/git2/transport.h +1 -1
  67. data/vendor/libgit2/include/git2/tree.h +2 -14
  68. data/vendor/libgit2/include/git2/types.h +9 -0
  69. data/vendor/libgit2/include/git2/version.h +3 -3
  70. data/vendor/libgit2/include/git2/worktree.h +1 -0
  71. data/vendor/libgit2/src/CMakeLists.txt +25 -4
  72. data/vendor/libgit2/src/alloc.c +21 -8
  73. data/vendor/libgit2/src/allocators/failalloc.c +92 -0
  74. data/vendor/libgit2/src/allocators/failalloc.h +23 -0
  75. data/vendor/libgit2/src/allocators/stdalloc.c +41 -10
  76. data/vendor/libgit2/src/allocators/win32_leakcheck.c +118 -0
  77. data/vendor/libgit2/src/allocators/{win32_crtdbg.h → win32_leakcheck.h} +3 -3
  78. data/vendor/libgit2/src/annotated_commit.c +21 -9
  79. data/vendor/libgit2/src/apply.c +16 -7
  80. data/vendor/libgit2/src/array.h +11 -11
  81. data/vendor/libgit2/src/attr.c +181 -74
  82. data/vendor/libgit2/src/attr_file.c +84 -39
  83. data/vendor/libgit2/src/attr_file.h +32 -11
  84. data/vendor/libgit2/src/attrcache.c +42 -37
  85. data/vendor/libgit2/src/attrcache.h +4 -5
  86. data/vendor/libgit2/src/blame.c +26 -15
  87. data/vendor/libgit2/src/blob.c +44 -24
  88. data/vendor/libgit2/src/branch.c +69 -17
  89. data/vendor/libgit2/src/buffer.c +334 -25
  90. data/vendor/libgit2/src/buffer.h +153 -2
  91. data/vendor/libgit2/src/cache.c +2 -2
  92. data/vendor/libgit2/src/cache.h +7 -7
  93. data/vendor/libgit2/src/cc-compat.h +10 -2
  94. data/vendor/libgit2/src/checkout.c +48 -26
  95. data/vendor/libgit2/src/cherrypick.c +6 -2
  96. data/vendor/libgit2/src/clone.c +26 -11
  97. data/vendor/libgit2/src/commit.c +41 -28
  98. data/vendor/libgit2/src/commit_graph.c +1209 -0
  99. data/vendor/libgit2/src/commit_graph.h +162 -0
  100. data/vendor/libgit2/src/commit_list.c +46 -0
  101. data/vendor/libgit2/src/commit_list.h +2 -0
  102. data/vendor/libgit2/src/common.h +25 -2
  103. data/vendor/libgit2/src/config.c +37 -15
  104. data/vendor/libgit2/src/config_cache.c +9 -4
  105. data/vendor/libgit2/src/config_file.c +16 -8
  106. data/vendor/libgit2/src/config_parse.c +4 -6
  107. data/vendor/libgit2/src/crlf.c +16 -6
  108. data/vendor/libgit2/src/date.c +4 -3
  109. data/vendor/libgit2/src/delta.c +1 -1
  110. data/vendor/libgit2/src/describe.c +6 -3
  111. data/vendor/libgit2/src/diff.c +11 -8
  112. data/vendor/libgit2/src/diff_driver.c +21 -17
  113. data/vendor/libgit2/src/diff_file.c +2 -6
  114. data/vendor/libgit2/src/diff_generate.c +46 -17
  115. data/vendor/libgit2/src/diff_print.c +19 -6
  116. data/vendor/libgit2/src/diff_stats.c +7 -5
  117. data/vendor/libgit2/src/diff_tform.c +11 -10
  118. data/vendor/libgit2/src/diff_xdiff.c +4 -2
  119. data/vendor/libgit2/src/diff_xdiff.h +1 -1
  120. data/vendor/libgit2/src/errors.c +24 -19
  121. data/vendor/libgit2/src/features.h.in +5 -1
  122. data/vendor/libgit2/src/fetch.c +5 -2
  123. data/vendor/libgit2/src/fetchhead.c +8 -4
  124. data/vendor/libgit2/src/filebuf.c +9 -7
  125. data/vendor/libgit2/src/filter.c +206 -110
  126. data/vendor/libgit2/src/filter.h +24 -5
  127. data/vendor/libgit2/src/futils.c +5 -5
  128. data/vendor/libgit2/src/futils.h +1 -1
  129. data/vendor/libgit2/src/graph.c +64 -9
  130. data/vendor/libgit2/src/hash/sha1/collisiondetect.c +3 -3
  131. data/vendor/libgit2/src/hash/sha1/common_crypto.c +3 -3
  132. data/vendor/libgit2/src/hash/sha1/generic.h +1 -1
  133. data/vendor/libgit2/src/hash/sha1/mbedtls.c +12 -12
  134. data/vendor/libgit2/src/hash/sha1/openssl.c +3 -3
  135. data/vendor/libgit2/src/hash/sha1/sha1dc/sha1.c +0 -2
  136. data/vendor/libgit2/src/hash/sha1/win32.c +15 -11
  137. data/vendor/libgit2/src/hash.c +16 -13
  138. data/vendor/libgit2/src/hash.h +1 -1
  139. data/vendor/libgit2/src/hashsig.c +23 -10
  140. data/vendor/libgit2/src/ident.c +13 -3
  141. data/vendor/libgit2/src/ignore.c +35 -19
  142. data/vendor/libgit2/src/index.c +112 -75
  143. data/vendor/libgit2/src/index.h +1 -1
  144. data/vendor/libgit2/src/indexer.c +50 -32
  145. data/vendor/libgit2/src/integer.h +79 -2
  146. data/vendor/libgit2/src/iterator.c +36 -24
  147. data/vendor/libgit2/src/iterator.h +1 -1
  148. data/vendor/libgit2/src/khash.h +2 -11
  149. data/vendor/libgit2/src/{settings.c → libgit2.c} +117 -50
  150. data/vendor/libgit2/src/libgit2.h +15 -0
  151. data/vendor/libgit2/src/mailmap.c +23 -10
  152. data/vendor/libgit2/src/map.h +3 -3
  153. data/vendor/libgit2/src/merge.c +75 -32
  154. data/vendor/libgit2/src/merge.h +2 -1
  155. data/vendor/libgit2/src/merge_driver.c +19 -13
  156. data/vendor/libgit2/src/merge_file.c +11 -3
  157. data/vendor/libgit2/src/message.c +3 -1
  158. data/vendor/libgit2/src/midx.c +471 -10
  159. data/vendor/libgit2/src/midx.h +28 -1
  160. data/vendor/libgit2/src/mwindow.c +106 -60
  161. data/vendor/libgit2/src/mwindow.h +3 -3
  162. data/vendor/libgit2/src/net.c +127 -3
  163. data/vendor/libgit2/src/net.h +16 -2
  164. data/vendor/libgit2/src/netops.c +6 -4
  165. data/vendor/libgit2/src/netops.h +2 -2
  166. data/vendor/libgit2/src/notes.c +10 -10
  167. data/vendor/libgit2/src/object.c +22 -14
  168. data/vendor/libgit2/src/odb.c +289 -51
  169. data/vendor/libgit2/src/odb.h +16 -2
  170. data/vendor/libgit2/src/odb_loose.c +28 -18
  171. data/vendor/libgit2/src/odb_mempack.c +1 -1
  172. data/vendor/libgit2/src/odb_pack.c +391 -114
  173. data/vendor/libgit2/src/oid.c +5 -4
  174. data/vendor/libgit2/src/pack-objects.c +54 -48
  175. data/vendor/libgit2/src/pack.c +339 -125
  176. data/vendor/libgit2/src/pack.h +25 -7
  177. data/vendor/libgit2/src/patch.c +14 -7
  178. data/vendor/libgit2/src/patch_generate.c +2 -2
  179. data/vendor/libgit2/src/patch_parse.c +2 -1
  180. data/vendor/libgit2/src/path.c +98 -53
  181. data/vendor/libgit2/src/path.h +79 -6
  182. data/vendor/libgit2/src/pathspec.c +8 -8
  183. data/vendor/libgit2/src/pool.c +13 -7
  184. data/vendor/libgit2/src/posix.c +43 -12
  185. data/vendor/libgit2/src/posix.h +9 -0
  186. data/vendor/libgit2/src/reader.c +10 -6
  187. data/vendor/libgit2/src/rebase.c +93 -49
  188. data/vendor/libgit2/src/refdb.c +30 -13
  189. data/vendor/libgit2/src/refdb_fs.c +125 -71
  190. data/vendor/libgit2/src/reflog.c +19 -14
  191. data/vendor/libgit2/src/refs.c +91 -43
  192. data/vendor/libgit2/src/refs.h +1 -1
  193. data/vendor/libgit2/src/refspec.c +80 -44
  194. data/vendor/libgit2/src/remote.c +281 -105
  195. data/vendor/libgit2/src/remote.h +2 -1
  196. data/vendor/libgit2/src/repository.c +191 -118
  197. data/vendor/libgit2/src/repository.h +13 -2
  198. data/vendor/libgit2/src/reset.c +7 -6
  199. data/vendor/libgit2/src/revert.c +6 -2
  200. data/vendor/libgit2/src/revparse.c +14 -9
  201. data/vendor/libgit2/src/revwalk.c +32 -15
  202. data/vendor/libgit2/src/runtime.c +162 -0
  203. data/vendor/libgit2/src/runtime.h +62 -0
  204. data/vendor/libgit2/src/settings.h +11 -0
  205. data/vendor/libgit2/src/signature.c +6 -5
  206. data/vendor/libgit2/src/sortedcache.h +10 -8
  207. data/vendor/libgit2/src/stash.c +3 -1
  208. data/vendor/libgit2/src/status.c +7 -4
  209. data/vendor/libgit2/src/strarray.c +2 -1
  210. data/vendor/libgit2/src/streams/mbedtls.c +14 -17
  211. data/vendor/libgit2/src/streams/mbedtls.h +1 -1
  212. data/vendor/libgit2/src/streams/openssl.c +101 -201
  213. data/vendor/libgit2/src/streams/openssl.h +9 -1
  214. data/vendor/libgit2/src/streams/openssl_dynamic.c +309 -0
  215. data/vendor/libgit2/src/streams/openssl_dynamic.h +348 -0
  216. data/vendor/libgit2/src/streams/openssl_legacy.c +203 -0
  217. data/vendor/libgit2/src/streams/openssl_legacy.h +63 -0
  218. data/vendor/libgit2/src/streams/registry.c +5 -6
  219. data/vendor/libgit2/src/streams/socket.c +6 -2
  220. data/vendor/libgit2/src/streams/stransport.c +6 -3
  221. data/vendor/libgit2/src/streams/tls.c +5 -3
  222. data/vendor/libgit2/src/submodule.c +128 -62
  223. data/vendor/libgit2/src/submodule.h +9 -9
  224. data/vendor/libgit2/src/sysdir.c +4 -6
  225. data/vendor/libgit2/src/tag.c +47 -11
  226. data/vendor/libgit2/src/thread.c +140 -0
  227. data/vendor/libgit2/src/thread.h +479 -0
  228. data/vendor/libgit2/src/threadstate.c +83 -0
  229. data/vendor/libgit2/src/threadstate.h +24 -0
  230. data/vendor/libgit2/src/trace.c +2 -2
  231. data/vendor/libgit2/src/trace.h +17 -13
  232. data/vendor/libgit2/src/transaction.c +19 -8
  233. data/vendor/libgit2/src/transport.c +3 -3
  234. data/vendor/libgit2/src/transports/auth.c +1 -1
  235. data/vendor/libgit2/src/transports/auth_negotiate.c +11 -4
  236. data/vendor/libgit2/src/transports/auth_ntlm.c +10 -6
  237. data/vendor/libgit2/src/transports/credential.c +15 -7
  238. data/vendor/libgit2/src/transports/git.c +1 -3
  239. data/vendor/libgit2/src/transports/http.c +19 -17
  240. data/vendor/libgit2/src/transports/http.h +1 -0
  241. data/vendor/libgit2/src/transports/httpclient.c +62 -30
  242. data/vendor/libgit2/src/transports/httpclient.h +1 -1
  243. data/vendor/libgit2/src/transports/local.c +3 -3
  244. data/vendor/libgit2/src/transports/smart.c +12 -7
  245. data/vendor/libgit2/src/transports/smart.h +1 -1
  246. data/vendor/libgit2/src/transports/smart_protocol.c +11 -5
  247. data/vendor/libgit2/src/transports/ssh.c +51 -17
  248. data/vendor/libgit2/src/transports/winhttp.c +138 -81
  249. data/vendor/libgit2/src/tree.c +100 -77
  250. data/vendor/libgit2/src/tree.h +1 -0
  251. data/vendor/libgit2/src/tsort.c +0 -2
  252. data/vendor/libgit2/src/unix/map.c +3 -1
  253. data/vendor/libgit2/src/unix/posix.h +3 -0
  254. data/vendor/libgit2/src/unix/pthread.h +2 -1
  255. data/vendor/libgit2/src/utf8.c +150 -0
  256. data/vendor/libgit2/src/utf8.h +52 -0
  257. data/vendor/libgit2/src/util.c +53 -129
  258. data/vendor/libgit2/src/util.h +33 -39
  259. data/vendor/libgit2/src/vector.c +23 -19
  260. data/vendor/libgit2/src/vector.h +4 -2
  261. data/vendor/libgit2/src/win32/findfile.c +4 -2
  262. data/vendor/libgit2/src/win32/map.c +1 -1
  263. data/vendor/libgit2/src/win32/msvc-compat.h +9 -1
  264. data/vendor/libgit2/src/win32/path_w32.c +22 -24
  265. data/vendor/libgit2/src/win32/path_w32.h +0 -1
  266. data/vendor/libgit2/src/win32/posix_w32.c +77 -1
  267. data/vendor/libgit2/src/win32/precompiled.h +0 -1
  268. data/vendor/libgit2/src/win32/reparse.h +4 -4
  269. data/vendor/libgit2/src/win32/thread.c +24 -15
  270. data/vendor/libgit2/src/win32/thread.h +1 -1
  271. data/vendor/libgit2/src/win32/w32_buffer.c +3 -3
  272. data/vendor/libgit2/src/win32/w32_common.h +18 -9
  273. data/vendor/libgit2/src/win32/{w32_crtdbg_stacktrace.c → w32_leakcheck.c} +269 -33
  274. data/vendor/libgit2/src/win32/w32_leakcheck.h +222 -0
  275. data/vendor/libgit2/src/win32/w32_util.h +6 -6
  276. data/vendor/libgit2/src/worktree.c +32 -14
  277. data/vendor/libgit2/src/zstream.c +1 -1
  278. metadata +32 -16
  279. data/vendor/libgit2/src/allocators/win32_crtdbg.c +0 -118
  280. data/vendor/libgit2/src/buf_text.c +0 -316
  281. data/vendor/libgit2/src/buf_text.h +0 -122
  282. data/vendor/libgit2/src/global.c +0 -363
  283. data/vendor/libgit2/src/global.h +0 -41
  284. data/vendor/libgit2/src/thread-utils.c +0 -58
  285. data/vendor/libgit2/src/thread-utils.h +0 -364
  286. data/vendor/libgit2/src/win32/w32_crtdbg_stacktrace.h +0 -127
  287. data/vendor/libgit2/src/win32/w32_stack.c +0 -188
  288. data/vendor/libgit2/src/win32/w32_stack.h +0 -140
@@ -23,14 +23,14 @@
23
23
 
24
24
  #define GIT_ALTERNATES_FILE "info/alternates"
25
25
 
26
+ #define GIT_ALTERNATES_MAX_DEPTH 5
27
+
26
28
  /*
27
29
  * We work under the assumption that most objects for long-running
28
30
  * operations will be packed
29
31
  */
30
- #define GIT_LOOSE_PRIORITY 1
31
- #define GIT_PACKED_PRIORITY 2
32
-
33
- #define GIT_ALTERNATES_MAX_DEPTH 5
32
+ int git_odb__loose_priority = GIT_ODB_DEFAULT_LOOSE_PRIORITY;
33
+ int git_odb__packed_priority = GIT_ODB_DEFAULT_PACKED_PRIORITY;
34
34
 
35
35
  bool git_odb__strict_hash_verification = true;
36
36
 
@@ -114,7 +114,8 @@ int git_odb__hashobj(git_oid *id, git_rawobj *obj)
114
114
  size_t hdrlen;
115
115
  int error;
116
116
 
117
- assert(id && obj);
117
+ GIT_ASSERT_ARG(id);
118
+ GIT_ASSERT_ARG(obj);
118
119
 
119
120
  if (!git_object_typeisloose(obj->type)) {
120
121
  git_error_set(GIT_ERROR_INVALID, "invalid object type");
@@ -259,9 +260,7 @@ int git_odb__hashfd_filtered(
259
260
  if (!(error = git_futils_readbuffer_fd(&raw, fd, size))) {
260
261
  git_buf post = GIT_BUF_INIT;
261
262
 
262
- error = git_filter_list_apply_to_data(&post, fl, &raw);
263
-
264
- git_buf_dispose(&raw);
263
+ error = git_filter_list__convert_buf(&post, fl, &raw);
265
264
 
266
265
  if (!error)
267
266
  error = git_odb_hash(out, post.ptr, post.size, type);
@@ -298,14 +297,15 @@ int git_odb__hashlink(git_oid *out, const char *path)
298
297
  GIT_ERROR_CHECK_ALLOC(link_data);
299
298
 
300
299
  read_len = p_readlink(path, link_data, size);
301
- link_data[size] = '\0';
302
- if (read_len != size) {
300
+ if (read_len == -1) {
303
301
  git_error_set(GIT_ERROR_OS, "failed to read symlink data for '%s'", path);
304
302
  git__free(link_data);
305
303
  return -1;
306
304
  }
305
+ GIT_ASSERT(read_len <= size);
306
+ link_data[read_len] = '\0';
307
307
 
308
- result = git_odb_hash(out, link_data, size, GIT_OBJECT_BLOB);
308
+ result = git_odb_hash(out, link_data, read_len, GIT_OBJECT_BLOB);
309
309
  git__free(link_data);
310
310
  } else {
311
311
  int fd = git_futils_open_ro(path);
@@ -346,7 +346,7 @@ int git_odb_hash(git_oid *id, const void *data, size_t len, git_object_t type)
346
346
  {
347
347
  git_rawobj raw;
348
348
 
349
- assert(id);
349
+ GIT_ASSERT_ARG(id);
350
350
 
351
351
  raw.data = (void *)data;
352
352
  raw.len = len;
@@ -376,7 +376,7 @@ static int fake_wstream__write(git_odb_stream *_stream, const char *data, size_t
376
376
  {
377
377
  fake_wstream *stream = (fake_wstream *)_stream;
378
378
 
379
- assert(stream->written + len <= stream->size);
379
+ GIT_ASSERT(stream->written + len <= stream->size);
380
380
 
381
381
  memcpy(stream->buffer + stream->written, data, len);
382
382
  stream->written += len;
@@ -449,12 +449,18 @@ int git_odb_new(git_odb **out)
449
449
  git_odb *db = git__calloc(1, sizeof(*db));
450
450
  GIT_ERROR_CHECK_ALLOC(db);
451
451
 
452
+ if (git_mutex_init(&db->lock) < 0) {
453
+ git__free(db);
454
+ return -1;
455
+ }
452
456
  if (git_cache_init(&db->own_cache) < 0) {
457
+ git_mutex_free(&db->lock);
453
458
  git__free(db);
454
459
  return -1;
455
460
  }
456
461
  if (git_vector_init(&db->backends, 4, backend_sort_cmp) < 0) {
457
462
  git_cache_dispose(&db->own_cache);
463
+ git_mutex_free(&db->lock);
458
464
  git__free(db);
459
465
  return -1;
460
466
  }
@@ -470,12 +476,13 @@ static int add_backend_internal(
470
476
  {
471
477
  backend_internal *internal;
472
478
 
473
- assert(odb && backend);
479
+ GIT_ASSERT_ARG(odb);
480
+ GIT_ASSERT_ARG(backend);
474
481
 
475
482
  GIT_ERROR_CHECK_VERSION(backend, GIT_ODB_BACKEND_VERSION, "git_odb_backend");
476
483
 
477
484
  /* Check if the backend is already owned by another ODB */
478
- assert(!backend->odb || backend->odb == odb);
485
+ GIT_ASSERT(!backend->odb || backend->odb == odb);
479
486
 
480
487
  internal = git__malloc(sizeof(backend_internal));
481
488
  GIT_ERROR_CHECK_ALLOC(internal);
@@ -485,13 +492,18 @@ static int add_backend_internal(
485
492
  internal->is_alternate = is_alternate;
486
493
  internal->disk_inode = disk_inode;
487
494
 
495
+ if (git_mutex_lock(&odb->lock) < 0) {
496
+ git_error_set(GIT_ERROR_ODB, "failed to acquire the odb lock");
497
+ return -1;
498
+ }
488
499
  if (git_vector_insert(&odb->backends, internal) < 0) {
500
+ git_mutex_unlock(&odb->lock);
489
501
  git__free(internal);
490
502
  return -1;
491
503
  }
492
-
493
504
  git_vector_sort(&odb->backends);
494
505
  internal->backend->odb = odb;
506
+ git_mutex_unlock(&odb->lock);
495
507
  return 0;
496
508
  }
497
509
 
@@ -507,8 +519,19 @@ int git_odb_add_alternate(git_odb *odb, git_odb_backend *backend, int priority)
507
519
 
508
520
  size_t git_odb_num_backends(git_odb *odb)
509
521
  {
510
- assert(odb);
511
- return odb->backends.length;
522
+ size_t length;
523
+ bool locked = true;
524
+
525
+ GIT_ASSERT_ARG(odb);
526
+
527
+ if (git_mutex_lock(&odb->lock) < 0) {
528
+ git_error_set(GIT_ERROR_ODB, "failed to acquire the odb lock");
529
+ locked = false;
530
+ }
531
+ length = odb->backends.length;
532
+ if (locked)
533
+ git_mutex_unlock(&odb->lock);
534
+ return length;
512
535
  }
513
536
 
514
537
  static int git_odb__error_unsupported_in_backend(const char *action)
@@ -522,24 +545,35 @@ static int git_odb__error_unsupported_in_backend(const char *action)
522
545
  int git_odb_get_backend(git_odb_backend **out, git_odb *odb, size_t pos)
523
546
  {
524
547
  backend_internal *internal;
548
+ int error;
549
+
550
+ GIT_ASSERT_ARG(out);
551
+ GIT_ASSERT_ARG(odb);
525
552
 
526
- assert(out && odb);
553
+
554
+ if ((error = git_mutex_lock(&odb->lock)) < 0) {
555
+ git_error_set(GIT_ERROR_ODB, "failed to acquire the odb lock");
556
+ return error;
557
+ }
527
558
  internal = git_vector_get(&odb->backends, pos);
528
559
 
529
- if (internal && internal->backend) {
530
- *out = internal->backend;
531
- return 0;
560
+ if (!internal || !internal->backend) {
561
+ git_mutex_unlock(&odb->lock);
562
+
563
+ git_error_set(GIT_ERROR_ODB, "no ODB backend loaded at index %" PRIuZ, pos);
564
+ return GIT_ENOTFOUND;
532
565
  }
566
+ *out = internal->backend;
567
+ git_mutex_unlock(&odb->lock);
533
568
 
534
- git_error_set(GIT_ERROR_ODB, "no ODB backend loaded at index %" PRIuZ, pos);
535
- return GIT_ENOTFOUND;
569
+ return 0;
536
570
  }
537
571
 
538
572
  int git_odb__add_default_backends(
539
573
  git_odb *db, const char *objects_dir,
540
574
  bool as_alternates, int alternate_depth)
541
575
  {
542
- size_t i;
576
+ size_t i = 0;
543
577
  struct stat st;
544
578
  ino_t inode;
545
579
  git_odb_backend *loose, *packed;
@@ -548,7 +582,7 @@ int git_odb__add_default_backends(
548
582
  * a cross-platform workaround for this */
549
583
  #ifdef GIT_WIN32
550
584
  GIT_UNUSED(i);
551
- GIT_UNUSED(st);
585
+ GIT_UNUSED(&st);
552
586
 
553
587
  inode = 0;
554
588
  #else
@@ -563,23 +597,40 @@ int git_odb__add_default_backends(
563
597
 
564
598
  inode = st.st_ino;
565
599
 
600
+ if (git_mutex_lock(&db->lock) < 0) {
601
+ git_error_set(GIT_ERROR_ODB, "failed to acquire the odb lock");
602
+ return -1;
603
+ }
566
604
  for (i = 0; i < db->backends.length; ++i) {
567
605
  backend_internal *backend = git_vector_get(&db->backends, i);
568
- if (backend->disk_inode == inode)
606
+ if (backend->disk_inode == inode) {
607
+ git_mutex_unlock(&db->lock);
569
608
  return 0;
609
+ }
570
610
  }
611
+ git_mutex_unlock(&db->lock);
571
612
  #endif
572
613
 
573
614
  /* add the loose object backend */
574
615
  if (git_odb_backend_loose(&loose, objects_dir, -1, db->do_fsync, 0, 0) < 0 ||
575
- add_backend_internal(db, loose, GIT_LOOSE_PRIORITY, as_alternates, inode) < 0)
616
+ add_backend_internal(db, loose, git_odb__loose_priority, as_alternates, inode) < 0)
576
617
  return -1;
577
618
 
578
619
  /* add the packed file backend */
579
620
  if (git_odb_backend_pack(&packed, objects_dir) < 0 ||
580
- add_backend_internal(db, packed, GIT_PACKED_PRIORITY, as_alternates, inode) < 0)
621
+ add_backend_internal(db, packed, git_odb__packed_priority, as_alternates, inode) < 0)
581
622
  return -1;
582
623
 
624
+ if (git_mutex_lock(&db->lock) < 0) {
625
+ git_error_set(GIT_ERROR_ODB, "failed to acquire the odb lock");
626
+ return -1;
627
+ }
628
+ if (!db->cgraph && git_commit_graph_new(&db->cgraph, objects_dir, false) < 0) {
629
+ git_mutex_unlock(&db->lock);
630
+ return -1;
631
+ }
632
+ git_mutex_unlock(&db->lock);
633
+
583
634
  return load_alternates(db, objects_dir, alternate_depth);
584
635
  }
585
636
 
@@ -641,11 +692,29 @@ int git_odb_add_disk_alternate(git_odb *odb, const char *path)
641
692
  return git_odb__add_default_backends(odb, path, true, 0);
642
693
  }
643
694
 
695
+ int git_odb_set_commit_graph(git_odb *odb, git_commit_graph *cgraph)
696
+ {
697
+ int error = 0;
698
+
699
+ GIT_ASSERT_ARG(odb);
700
+
701
+ if ((error = git_mutex_lock(&odb->lock)) < 0) {
702
+ git_error_set(GIT_ERROR_ODB, "failed to acquire the db lock");
703
+ return error;
704
+ }
705
+ git_commit_graph_free(odb->cgraph);
706
+ odb->cgraph = cgraph;
707
+ git_mutex_unlock(&odb->lock);
708
+
709
+ return error;
710
+ }
711
+
644
712
  int git_odb_open(git_odb **out, const char *objects_dir)
645
713
  {
646
714
  git_odb *db;
647
715
 
648
- assert(out && objects_dir);
716
+ GIT_ASSERT_ARG(out);
717
+ GIT_ASSERT_ARG(objects_dir);
649
718
 
650
719
  *out = NULL;
651
720
 
@@ -682,7 +751,12 @@ int git_odb__set_caps(git_odb *odb, int caps)
682
751
  static void odb_free(git_odb *db)
683
752
  {
684
753
  size_t i;
754
+ bool locked = true;
685
755
 
756
+ if (git_mutex_lock(&db->lock) < 0) {
757
+ git_error_set(GIT_ERROR_ODB, "failed to acquire the odb lock");
758
+ locked = false;
759
+ }
686
760
  for (i = 0; i < db->backends.length; ++i) {
687
761
  backend_internal *internal = git_vector_get(&db->backends, i);
688
762
  git_odb_backend *backend = internal->backend;
@@ -691,9 +765,13 @@ static void odb_free(git_odb *db)
691
765
 
692
766
  git__free(internal);
693
767
  }
768
+ if (locked)
769
+ git_mutex_unlock(&db->lock);
694
770
 
771
+ git_commit_graph_free(db->cgraph);
695
772
  git_vector_free(&db->backends);
696
773
  git_cache_dispose(&db->own_cache);
774
+ git_mutex_free(&db->lock);
697
775
 
698
776
  git__memzero(db, sizeof(*db));
699
777
  git__free(db);
@@ -714,7 +792,12 @@ static int odb_exists_1(
714
792
  {
715
793
  size_t i;
716
794
  bool found = false;
795
+ int error;
717
796
 
797
+ if ((error = git_mutex_lock(&db->lock)) < 0) {
798
+ git_error_set(GIT_ERROR_ODB, "failed to acquire the odb lock");
799
+ return error;
800
+ }
718
801
  for (i = 0; i < db->backends.length && !found; ++i) {
719
802
  backend_internal *internal = git_vector_get(&db->backends, i);
720
803
  git_odb_backend *b = internal->backend;
@@ -725,10 +808,34 @@ static int odb_exists_1(
725
808
  if (b->exists != NULL)
726
809
  found = (bool)b->exists(b, id);
727
810
  }
811
+ git_mutex_unlock(&db->lock);
728
812
 
729
813
  return (int)found;
730
814
  }
731
815
 
816
+ int git_odb__get_commit_graph_file(git_commit_graph_file **out, git_odb *db)
817
+ {
818
+ int error = 0;
819
+ git_commit_graph_file *result = NULL;
820
+
821
+ if ((error = git_mutex_lock(&db->lock)) < 0) {
822
+ git_error_set(GIT_ERROR_ODB, "failed to acquire the db lock");
823
+ return error;
824
+ }
825
+ if (!db->cgraph) {
826
+ error = GIT_ENOTFOUND;
827
+ goto done;
828
+ }
829
+ error = git_commit_graph_get_file(&result, db->cgraph);
830
+ if (error)
831
+ goto done;
832
+ *out = result;
833
+
834
+ done:
835
+ git_mutex_unlock(&db->lock);
836
+ return error;
837
+ }
838
+
732
839
  static int odb_freshen_1(
733
840
  git_odb *db,
734
841
  const git_oid *id,
@@ -736,7 +843,12 @@ static int odb_freshen_1(
736
843
  {
737
844
  size_t i;
738
845
  bool found = false;
846
+ int error;
739
847
 
848
+ if ((error = git_mutex_lock(&db->lock)) < 0) {
849
+ git_error_set(GIT_ERROR_ODB, "failed to acquire the odb lock");
850
+ return error;
851
+ }
740
852
  for (i = 0; i < db->backends.length && !found; ++i) {
741
853
  backend_internal *internal = git_vector_get(&db->backends, i);
742
854
  git_odb_backend *b = internal->backend;
@@ -749,13 +861,15 @@ static int odb_freshen_1(
749
861
  else if (b->exists != NULL)
750
862
  found = b->exists(b, id);
751
863
  }
864
+ git_mutex_unlock(&db->lock);
752
865
 
753
866
  return (int)found;
754
867
  }
755
868
 
756
869
  int git_odb__freshen(git_odb *db, const git_oid *id)
757
870
  {
758
- assert(db && id);
871
+ GIT_ASSERT_ARG(db);
872
+ GIT_ASSERT_ARG(id);
759
873
 
760
874
  if (odb_freshen_1(db, id, false))
761
875
  return 1;
@@ -771,7 +885,8 @@ int git_odb_exists(git_odb *db, const git_oid *id)
771
885
  {
772
886
  git_odb_object *object;
773
887
 
774
- assert(db && id);
888
+ GIT_ASSERT_ARG(db);
889
+ GIT_ASSERT_ARG(id);
775
890
 
776
891
  if (git_oid_is_zero(id))
777
892
  return 0;
@@ -798,6 +913,11 @@ static int odb_exists_prefix_1(git_oid *out, git_odb *db,
798
913
  int error = GIT_ENOTFOUND, num_found = 0;
799
914
  git_oid last_found = {{0}}, found;
800
915
 
916
+ if ((error = git_mutex_lock(&db->lock)) < 0) {
917
+ git_error_set(GIT_ERROR_ODB, "failed to acquire the odb lock");
918
+ return error;
919
+ }
920
+ error = GIT_ENOTFOUND;
801
921
  for (i = 0; i < db->backends.length; ++i) {
802
922
  backend_internal *internal = git_vector_get(&db->backends, i);
803
923
  git_odb_backend *b = internal->backend;
@@ -811,18 +931,23 @@ static int odb_exists_prefix_1(git_oid *out, git_odb *db,
811
931
  error = b->exists_prefix(&found, b, key, len);
812
932
  if (error == GIT_ENOTFOUND || error == GIT_PASSTHROUGH)
813
933
  continue;
814
- if (error)
934
+ if (error) {
935
+ git_mutex_unlock(&db->lock);
815
936
  return error;
937
+ }
816
938
 
817
939
  /* make sure found item doesn't introduce ambiguity */
818
940
  if (num_found) {
819
- if (git_oid__cmp(&last_found, &found))
941
+ if (git_oid__cmp(&last_found, &found)) {
942
+ git_mutex_unlock(&db->lock);
820
943
  return git_odb__error_ambiguous("multiple matches for prefix");
944
+ }
821
945
  } else {
822
946
  git_oid_cpy(&last_found, &found);
823
947
  num_found++;
824
948
  }
825
949
  }
950
+ git_mutex_unlock(&db->lock);
826
951
 
827
952
  if (!num_found)
828
953
  return GIT_ENOTFOUND;
@@ -839,7 +964,8 @@ int git_odb_exists_prefix(
839
964
  int error;
840
965
  git_oid key = {{0}};
841
966
 
842
- assert(db && short_id);
967
+ GIT_ASSERT_ARG(db);
968
+ GIT_ASSERT_ARG(short_id);
843
969
 
844
970
  if (len < GIT_OID_MINPREFIXLEN)
845
971
  return git_odb__error_ambiguous("prefix length too short");
@@ -875,7 +1001,8 @@ int git_odb_expand_ids(
875
1001
  {
876
1002
  size_t i;
877
1003
 
878
- assert(db && ids);
1004
+ GIT_ASSERT_ARG(db);
1005
+ GIT_ASSERT_ARG(ids);
879
1006
 
880
1007
  for (i = 0; i < count; i++) {
881
1008
  git_odb_expand_id *query = &ids[i];
@@ -962,6 +1089,10 @@ static int odb_read_header_1(
962
1089
  return 0;
963
1090
  }
964
1091
 
1092
+ if ((error = git_mutex_lock(&db->lock)) < 0) {
1093
+ git_error_set(GIT_ERROR_ODB, "failed to acquire the odb lock");
1094
+ return error;
1095
+ }
965
1096
  for (i = 0; i < db->backends.length; ++i) {
966
1097
  backend_internal *internal = git_vector_get(&db->backends, i);
967
1098
  git_odb_backend *b = internal->backend;
@@ -983,9 +1114,11 @@ static int odb_read_header_1(
983
1114
  case GIT_ENOTFOUND:
984
1115
  break;
985
1116
  default:
1117
+ git_mutex_unlock(&db->lock);
986
1118
  return error;
987
1119
  }
988
1120
  }
1121
+ git_mutex_unlock(&db->lock);
989
1122
 
990
1123
  return passthrough ? GIT_PASSTHROUGH : GIT_ENOTFOUND;
991
1124
  }
@@ -997,7 +1130,11 @@ int git_odb__read_header_or_object(
997
1130
  int error = GIT_ENOTFOUND;
998
1131
  git_odb_object *object;
999
1132
 
1000
- assert(db && id && out && len_p && type_p);
1133
+ GIT_ASSERT_ARG(db);
1134
+ GIT_ASSERT_ARG(id);
1135
+ GIT_ASSERT_ARG(out);
1136
+ GIT_ASSERT_ARG(len_p);
1137
+ GIT_ASSERT_ARG(type_p);
1001
1138
 
1002
1139
  *out = NULL;
1003
1140
 
@@ -1054,6 +1191,10 @@ static int odb_read_1(git_odb_object **out, git_odb *db, const git_oid *id,
1054
1191
  return error;
1055
1192
  }
1056
1193
 
1194
+ if ((error = git_mutex_lock(&db->lock)) < 0) {
1195
+ git_error_set(GIT_ERROR_ODB, "failed to acquire the odb lock");
1196
+ return error;
1197
+ }
1057
1198
  for (i = 0; i < db->backends.length && !found; ++i) {
1058
1199
  backend_internal *internal = git_vector_get(&db->backends, i);
1059
1200
  git_odb_backend *b = internal->backend;
@@ -1066,12 +1207,15 @@ static int odb_read_1(git_odb_object **out, git_odb *db, const git_oid *id,
1066
1207
  if (error == GIT_PASSTHROUGH || error == GIT_ENOTFOUND)
1067
1208
  continue;
1068
1209
 
1069
- if (error < 0)
1210
+ if (error < 0) {
1211
+ git_mutex_unlock(&db->lock);
1070
1212
  return error;
1213
+ }
1071
1214
 
1072
1215
  found = true;
1073
1216
  }
1074
1217
  }
1218
+ git_mutex_unlock(&db->lock);
1075
1219
 
1076
1220
  if (!found)
1077
1221
  return GIT_ENOTFOUND;
@@ -1104,7 +1248,9 @@ int git_odb_read(git_odb_object **out, git_odb *db, const git_oid *id)
1104
1248
  {
1105
1249
  int error;
1106
1250
 
1107
- assert(out && db && id);
1251
+ GIT_ASSERT_ARG(out);
1252
+ GIT_ASSERT_ARG(db);
1253
+ GIT_ASSERT_ARG(id);
1108
1254
 
1109
1255
  if (git_oid_is_zero(id))
1110
1256
  return error_null_oid(GIT_ENOTFOUND, "cannot read object");
@@ -1162,6 +1308,10 @@ static int read_prefix_1(git_odb_object **out, git_odb *db,
1162
1308
  bool found = false;
1163
1309
  git_odb_object *object;
1164
1310
 
1311
+ if ((error = git_mutex_lock(&db->lock)) < 0) {
1312
+ git_error_set(GIT_ERROR_ODB, "failed to acquire the odb lock");
1313
+ return error;
1314
+ }
1165
1315
  for (i = 0; i < db->backends.length; ++i) {
1166
1316
  backend_internal *internal = git_vector_get(&db->backends, i);
1167
1317
  git_odb_backend *b = internal->backend;
@@ -1178,8 +1328,10 @@ static int read_prefix_1(git_odb_object **out, git_odb *db,
1178
1328
  continue;
1179
1329
  }
1180
1330
 
1181
- if (error)
1331
+ if (error) {
1332
+ git_mutex_unlock(&db->lock);
1182
1333
  goto out;
1334
+ }
1183
1335
 
1184
1336
  git__free(data);
1185
1337
  data = raw.data;
@@ -1194,6 +1346,7 @@ static int read_prefix_1(git_odb_object **out, git_odb *db,
1194
1346
 
1195
1347
  error = git_odb__error_ambiguous(buf.ptr);
1196
1348
  git_buf_dispose(&buf);
1349
+ git_mutex_unlock(&db->lock);
1197
1350
  goto out;
1198
1351
  }
1199
1352
 
@@ -1201,6 +1354,7 @@ static int read_prefix_1(git_odb_object **out, git_odb *db,
1201
1354
  found = true;
1202
1355
  }
1203
1356
  }
1357
+ git_mutex_unlock(&db->lock);
1204
1358
 
1205
1359
  if (!found)
1206
1360
  return GIT_ENOTFOUND;
@@ -1237,7 +1391,8 @@ int git_odb_read_prefix(
1237
1391
  git_oid key = {{0}};
1238
1392
  int error;
1239
1393
 
1240
- assert(out && db);
1394
+ GIT_ASSERT_ARG(out);
1395
+ GIT_ASSERT_ARG(db);
1241
1396
 
1242
1397
  if (len < GIT_OID_MINPREFIXLEN)
1243
1398
  return git_odb__error_ambiguous("prefix length too short");
@@ -1267,16 +1422,32 @@ int git_odb_read_prefix(
1267
1422
  int git_odb_foreach(git_odb *db, git_odb_foreach_cb cb, void *payload)
1268
1423
  {
1269
1424
  unsigned int i;
1425
+ git_vector backends = GIT_VECTOR_INIT;
1270
1426
  backend_internal *internal;
1427
+ int error = 0;
1428
+
1429
+ /* Make a copy of the backends vector to invoke the callback without holding the lock. */
1430
+ if ((error = git_mutex_lock(&db->lock)) < 0) {
1431
+ git_error_set(GIT_ERROR_ODB, "failed to acquire the odb lock");
1432
+ goto cleanup;
1433
+ }
1434
+ error = git_vector_dup(&backends, &db->backends, NULL);
1435
+ git_mutex_unlock(&db->lock);
1436
+
1437
+ if (error < 0)
1438
+ goto cleanup;
1271
1439
 
1272
- git_vector_foreach(&db->backends, i, internal) {
1440
+ git_vector_foreach(&backends, i, internal) {
1273
1441
  git_odb_backend *b = internal->backend;
1274
- int error = b->foreach(b, cb, payload);
1442
+ error = b->foreach(b, cb, payload);
1275
1443
  if (error != 0)
1276
- return error;
1444
+ goto cleanup;
1277
1445
  }
1278
1446
 
1279
- return 0;
1447
+ cleanup:
1448
+ git_vector_free(&backends);
1449
+
1450
+ return error;
1280
1451
  }
1281
1452
 
1282
1453
  int git_odb_write(
@@ -1286,7 +1457,8 @@ int git_odb_write(
1286
1457
  int error;
1287
1458
  git_odb_stream *stream;
1288
1459
 
1289
- assert(oid && db);
1460
+ GIT_ASSERT_ARG(oid);
1461
+ GIT_ASSERT_ARG(db);
1290
1462
 
1291
1463
  if ((error = git_odb_hash(oid, data, len, type)) < 0)
1292
1464
  return error;
@@ -1297,6 +1469,10 @@ int git_odb_write(
1297
1469
  if (git_odb__freshen(db, oid))
1298
1470
  return 0;
1299
1471
 
1472
+ if ((error = git_mutex_lock(&db->lock)) < 0) {
1473
+ git_error_set(GIT_ERROR_ODB, "failed to acquire the odb lock");
1474
+ return error;
1475
+ }
1300
1476
  for (i = 0, error = GIT_ERROR; i < db->backends.length && error < 0; ++i) {
1301
1477
  backend_internal *internal = git_vector_get(&db->backends, i);
1302
1478
  git_odb_backend *b = internal->backend;
@@ -1308,6 +1484,7 @@ int git_odb_write(
1308
1484
  if (b->write != NULL)
1309
1485
  error = b->write(b, oid, data, len, type);
1310
1486
  }
1487
+ git_mutex_unlock(&db->lock);
1311
1488
 
1312
1489
  if (!error || error == GIT_PASSTHROUGH)
1313
1490
  return 0;
@@ -1346,8 +1523,14 @@ int git_odb_open_wstream(
1346
1523
  int error = GIT_ERROR;
1347
1524
  git_hash_ctx *ctx = NULL;
1348
1525
 
1349
- assert(stream && db);
1526
+ GIT_ASSERT_ARG(stream);
1527
+ GIT_ASSERT_ARG(db);
1350
1528
 
1529
+ if ((error = git_mutex_lock(&db->lock)) < 0) {
1530
+ git_error_set(GIT_ERROR_ODB, "failed to acquire the odb lock");
1531
+ return error;
1532
+ }
1533
+ error = GIT_ERROR;
1351
1534
  for (i = 0; i < db->backends.length && error < 0; ++i) {
1352
1535
  backend_internal *internal = git_vector_get(&db->backends, i);
1353
1536
  git_odb_backend *b = internal->backend;
@@ -1364,6 +1547,7 @@ int git_odb_open_wstream(
1364
1547
  error = init_fake_wstream(stream, b, size, type);
1365
1548
  }
1366
1549
  }
1550
+ git_mutex_unlock(&db->lock);
1367
1551
 
1368
1552
  if (error < 0) {
1369
1553
  if (error == GIT_PASSTHROUGH)
@@ -1456,8 +1640,14 @@ int git_odb_open_rstream(
1456
1640
  size_t i, reads = 0;
1457
1641
  int error = GIT_ERROR;
1458
1642
 
1459
- assert(stream && db);
1643
+ GIT_ASSERT_ARG(stream);
1644
+ GIT_ASSERT_ARG(db);
1460
1645
 
1646
+ if ((error = git_mutex_lock(&db->lock)) < 0) {
1647
+ git_error_set(GIT_ERROR_ODB, "failed to acquire the odb lock");
1648
+ return error;
1649
+ }
1650
+ error = GIT_ERROR;
1461
1651
  for (i = 0; i < db->backends.length && error < 0; ++i) {
1462
1652
  backend_internal *internal = git_vector_get(&db->backends, i);
1463
1653
  git_odb_backend *b = internal->backend;
@@ -1467,6 +1657,7 @@ int git_odb_open_rstream(
1467
1657
  error = b->readstream(stream, len, type, b, oid);
1468
1658
  }
1469
1659
  }
1660
+ git_mutex_unlock(&db->lock);
1470
1661
 
1471
1662
  if (error == GIT_PASSTHROUGH)
1472
1663
  error = 0;
@@ -1481,8 +1672,14 @@ int git_odb_write_pack(struct git_odb_writepack **out, git_odb *db, git_indexer_
1481
1672
  size_t i, writes = 0;
1482
1673
  int error = GIT_ERROR;
1483
1674
 
1484
- assert(out && db);
1675
+ GIT_ASSERT_ARG(out);
1676
+ GIT_ASSERT_ARG(db);
1485
1677
 
1678
+ if ((error = git_mutex_lock(&db->lock)) < 0) {
1679
+ git_error_set(GIT_ERROR_ODB, "failed to acquire the odb lock");
1680
+ return error;
1681
+ }
1682
+ error = GIT_ERROR;
1486
1683
  for (i = 0; i < db->backends.length && error < 0; ++i) {
1487
1684
  backend_internal *internal = git_vector_get(&db->backends, i);
1488
1685
  git_odb_backend *b = internal->backend;
@@ -1496,6 +1693,7 @@ int git_odb_write_pack(struct git_odb_writepack **out, git_odb *db, git_indexer_
1496
1693
  error = b->writepack(out, b, db, progress_cb, progress_payload);
1497
1694
  }
1498
1695
  }
1696
+ git_mutex_unlock(&db->lock);
1499
1697
 
1500
1698
  if (error == GIT_PASSTHROUGH)
1501
1699
  error = 0;
@@ -1505,6 +1703,35 @@ int git_odb_write_pack(struct git_odb_writepack **out, git_odb *db, git_indexer_
1505
1703
  return error;
1506
1704
  }
1507
1705
 
1706
+ int git_odb_write_multi_pack_index(git_odb *db)
1707
+ {
1708
+ size_t i, writes = 0;
1709
+ int error = GIT_ERROR;
1710
+
1711
+ GIT_ASSERT_ARG(db);
1712
+
1713
+ for (i = 0; i < db->backends.length && error < 0; ++i) {
1714
+ backend_internal *internal = git_vector_get(&db->backends, i);
1715
+ git_odb_backend *b = internal->backend;
1716
+
1717
+ /* we don't write in alternates! */
1718
+ if (internal->is_alternate)
1719
+ continue;
1720
+
1721
+ if (b->writemidx != NULL) {
1722
+ ++writes;
1723
+ error = b->writemidx(b);
1724
+ }
1725
+ }
1726
+
1727
+ if (error == GIT_PASSTHROUGH)
1728
+ error = 0;
1729
+ if (error < 0 && !writes)
1730
+ error = git_odb__error_unsupported_in_backend("write multi-pack-index");
1731
+
1732
+ return error;
1733
+ }
1734
+
1508
1735
  void *git_odb_backend_data_alloc(git_odb_backend *backend, size_t len)
1509
1736
  {
1510
1737
  GIT_UNUSED(backend);
@@ -1527,18 +1754,29 @@ void git_odb_backend_data_free(git_odb_backend *backend, void *data)
1527
1754
  int git_odb_refresh(struct git_odb *db)
1528
1755
  {
1529
1756
  size_t i;
1530
- assert(db);
1757
+ int error;
1758
+
1759
+ GIT_ASSERT_ARG(db);
1531
1760
 
1761
+ if ((error = git_mutex_lock(&db->lock)) < 0) {
1762
+ git_error_set(GIT_ERROR_ODB, "failed to acquire the odb lock");
1763
+ return error;
1764
+ }
1532
1765
  for (i = 0; i < db->backends.length; ++i) {
1533
1766
  backend_internal *internal = git_vector_get(&db->backends, i);
1534
1767
  git_odb_backend *b = internal->backend;
1535
1768
 
1536
1769
  if (b->refresh != NULL) {
1537
1770
  int error = b->refresh(b);
1538
- if (error < 0)
1771
+ if (error < 0) {
1772
+ git_mutex_unlock(&db->lock);
1539
1773
  return error;
1774
+ }
1540
1775
  }
1541
1776
  }
1777
+ if (db->cgraph)
1778
+ git_commit_graph_refresh(db->cgraph);
1779
+ git_mutex_unlock(&db->lock);
1542
1780
 
1543
1781
  return 0;
1544
1782
  }