rugged 1.1.1 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (277) 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 +17 -5
  16. data/vendor/libgit2/deps/ntlmclient/crypt.h +14 -9
  17. data/vendor/libgit2/deps/ntlmclient/crypt_commoncrypto.c +20 -20
  18. data/vendor/libgit2/deps/ntlmclient/crypt_commoncrypto.h +3 -3
  19. data/vendor/libgit2/deps/ntlmclient/crypt_mbedtls.c +37 -36
  20. data/vendor/libgit2/deps/ntlmclient/crypt_mbedtls.h +4 -3
  21. data/vendor/libgit2/deps/ntlmclient/crypt_openssl.c +178 -51
  22. data/vendor/libgit2/deps/ntlmclient/crypt_openssl.h +74 -5
  23. data/vendor/libgit2/deps/ntlmclient/ntlm.c +150 -118
  24. data/vendor/libgit2/deps/ntlmclient/ntlm.h +13 -9
  25. data/vendor/libgit2/deps/ntlmclient/ntlmclient.h +16 -3
  26. data/vendor/libgit2/deps/ntlmclient/unicode.h +10 -4
  27. data/vendor/libgit2/deps/ntlmclient/unicode_builtin.c +16 -27
  28. data/vendor/libgit2/deps/ntlmclient/unicode_builtin.h +20 -0
  29. data/vendor/libgit2/deps/ntlmclient/unicode_iconv.c +28 -52
  30. data/vendor/libgit2/deps/ntlmclient/unicode_iconv.h +22 -0
  31. data/vendor/libgit2/include/git2/attr.h +89 -0
  32. data/vendor/libgit2/include/git2/blame.h +93 -42
  33. data/vendor/libgit2/include/git2/blob.h +14 -2
  34. data/vendor/libgit2/include/git2/branch.h +25 -0
  35. data/vendor/libgit2/include/git2/cert.h +42 -5
  36. data/vendor/libgit2/include/git2/checkout.h +28 -12
  37. data/vendor/libgit2/include/git2/commit.h +35 -19
  38. data/vendor/libgit2/include/git2/common.h +14 -4
  39. data/vendor/libgit2/include/git2/deprecated.h +206 -6
  40. data/vendor/libgit2/include/git2/diff.h +34 -19
  41. data/vendor/libgit2/include/git2/errors.h +6 -6
  42. data/vendor/libgit2/include/git2/filter.h +57 -17
  43. data/vendor/libgit2/include/git2/graph.h +20 -2
  44. data/vendor/libgit2/include/git2/index.h +2 -2
  45. data/vendor/libgit2/include/git2/odb.h +29 -0
  46. data/vendor/libgit2/include/git2/patch.h +8 -0
  47. data/vendor/libgit2/include/git2/rebase.h +25 -1
  48. data/vendor/libgit2/include/git2/refs.h +6 -2
  49. data/vendor/libgit2/include/git2/remote.h +59 -6
  50. data/vendor/libgit2/include/git2/revparse.h +5 -5
  51. data/vendor/libgit2/include/git2/status.h +115 -59
  52. data/vendor/libgit2/include/git2/submodule.h +9 -0
  53. data/vendor/libgit2/include/git2/sys/commit_graph.h +174 -0
  54. data/vendor/libgit2/include/git2/sys/filter.h +49 -28
  55. data/vendor/libgit2/include/git2/sys/midx.h +74 -0
  56. data/vendor/libgit2/include/git2/sys/odb_backend.h +7 -0
  57. data/vendor/libgit2/include/git2/sys/transport.h +1 -0
  58. data/vendor/libgit2/include/git2/tag.h +12 -0
  59. data/vendor/libgit2/include/git2/tree.h +0 -14
  60. data/vendor/libgit2/include/git2/types.h +9 -0
  61. data/vendor/libgit2/include/git2/version.h +4 -4
  62. data/vendor/libgit2/include/git2/worktree.h +1 -0
  63. data/vendor/libgit2/src/CMakeLists.txt +25 -4
  64. data/vendor/libgit2/src/alloc.c +21 -8
  65. data/vendor/libgit2/src/allocators/failalloc.c +92 -0
  66. data/vendor/libgit2/src/allocators/failalloc.h +23 -0
  67. data/vendor/libgit2/src/allocators/stdalloc.c +41 -10
  68. data/vendor/libgit2/src/allocators/win32_leakcheck.c +118 -0
  69. data/vendor/libgit2/src/allocators/{win32_crtdbg.h → win32_leakcheck.h} +3 -3
  70. data/vendor/libgit2/src/annotated_commit.c +21 -9
  71. data/vendor/libgit2/src/apply.c +16 -7
  72. data/vendor/libgit2/src/array.h +11 -11
  73. data/vendor/libgit2/src/attr.c +181 -74
  74. data/vendor/libgit2/src/attr_file.c +84 -39
  75. data/vendor/libgit2/src/attr_file.h +32 -11
  76. data/vendor/libgit2/src/attrcache.c +42 -37
  77. data/vendor/libgit2/src/attrcache.h +4 -5
  78. data/vendor/libgit2/src/blame.c +11 -5
  79. data/vendor/libgit2/src/blob.c +35 -24
  80. data/vendor/libgit2/src/branch.c +69 -17
  81. data/vendor/libgit2/src/buffer.c +334 -25
  82. data/vendor/libgit2/src/buffer.h +153 -2
  83. data/vendor/libgit2/src/cache.c +2 -2
  84. data/vendor/libgit2/src/cache.h +7 -7
  85. data/vendor/libgit2/src/cc-compat.h +10 -2
  86. data/vendor/libgit2/src/checkout.c +48 -26
  87. data/vendor/libgit2/src/cherrypick.c +6 -2
  88. data/vendor/libgit2/src/clone.c +41 -47
  89. data/vendor/libgit2/src/commit.c +41 -28
  90. data/vendor/libgit2/src/commit_graph.c +1209 -0
  91. data/vendor/libgit2/src/commit_graph.h +162 -0
  92. data/vendor/libgit2/src/commit_list.c +46 -0
  93. data/vendor/libgit2/src/commit_list.h +2 -0
  94. data/vendor/libgit2/src/common.h +25 -2
  95. data/vendor/libgit2/src/config.c +37 -15
  96. data/vendor/libgit2/src/config_cache.c +5 -3
  97. data/vendor/libgit2/src/config_file.c +16 -8
  98. data/vendor/libgit2/src/config_parse.c +4 -6
  99. data/vendor/libgit2/src/crlf.c +16 -6
  100. data/vendor/libgit2/src/date.c +4 -3
  101. data/vendor/libgit2/src/delta.c +1 -1
  102. data/vendor/libgit2/src/describe.c +6 -3
  103. data/vendor/libgit2/src/diff.c +11 -8
  104. data/vendor/libgit2/src/diff_driver.c +21 -17
  105. data/vendor/libgit2/src/diff_file.c +2 -6
  106. data/vendor/libgit2/src/diff_generate.c +46 -17
  107. data/vendor/libgit2/src/diff_print.c +19 -6
  108. data/vendor/libgit2/src/diff_stats.c +7 -5
  109. data/vendor/libgit2/src/diff_tform.c +9 -8
  110. data/vendor/libgit2/src/diff_xdiff.c +4 -2
  111. data/vendor/libgit2/src/diff_xdiff.h +1 -1
  112. data/vendor/libgit2/src/errors.c +24 -19
  113. data/vendor/libgit2/src/features.h.in +5 -1
  114. data/vendor/libgit2/src/fetch.c +5 -2
  115. data/vendor/libgit2/src/fetchhead.c +8 -4
  116. data/vendor/libgit2/src/filebuf.c +9 -7
  117. data/vendor/libgit2/src/filter.c +206 -110
  118. data/vendor/libgit2/src/filter.h +24 -5
  119. data/vendor/libgit2/src/futils.c +5 -5
  120. data/vendor/libgit2/src/futils.h +1 -1
  121. data/vendor/libgit2/src/graph.c +64 -9
  122. data/vendor/libgit2/src/hash/sha1/collisiondetect.c +3 -3
  123. data/vendor/libgit2/src/hash/sha1/common_crypto.c +3 -3
  124. data/vendor/libgit2/src/hash/sha1/generic.h +1 -1
  125. data/vendor/libgit2/src/hash/sha1/mbedtls.c +12 -12
  126. data/vendor/libgit2/src/hash/sha1/openssl.c +3 -3
  127. data/vendor/libgit2/src/hash/sha1/sha1dc/sha1.c +0 -2
  128. data/vendor/libgit2/src/hash/sha1/win32.c +15 -11
  129. data/vendor/libgit2/src/hash.c +16 -13
  130. data/vendor/libgit2/src/hash.h +1 -1
  131. data/vendor/libgit2/src/hashsig.c +23 -10
  132. data/vendor/libgit2/src/ident.c +13 -3
  133. data/vendor/libgit2/src/ignore.c +35 -19
  134. data/vendor/libgit2/src/index.c +106 -70
  135. data/vendor/libgit2/src/index.h +1 -1
  136. data/vendor/libgit2/src/indexer.c +31 -29
  137. data/vendor/libgit2/src/integer.h +64 -2
  138. data/vendor/libgit2/src/iterator.c +36 -24
  139. data/vendor/libgit2/src/iterator.h +1 -1
  140. data/vendor/libgit2/src/khash.h +2 -11
  141. data/vendor/libgit2/src/{settings.c → libgit2.c} +117 -50
  142. data/vendor/libgit2/src/libgit2.h +15 -0
  143. data/vendor/libgit2/src/mailmap.c +23 -10
  144. data/vendor/libgit2/src/map.h +3 -3
  145. data/vendor/libgit2/src/merge.c +70 -30
  146. data/vendor/libgit2/src/merge.h +2 -1
  147. data/vendor/libgit2/src/merge_driver.c +19 -13
  148. data/vendor/libgit2/src/merge_file.c +11 -3
  149. data/vendor/libgit2/src/message.c +3 -1
  150. data/vendor/libgit2/src/midx.c +471 -10
  151. data/vendor/libgit2/src/midx.h +28 -1
  152. data/vendor/libgit2/src/mwindow.c +103 -59
  153. data/vendor/libgit2/src/mwindow.h +3 -3
  154. data/vendor/libgit2/src/net.c +127 -3
  155. data/vendor/libgit2/src/net.h +16 -2
  156. data/vendor/libgit2/src/netops.c +6 -4
  157. data/vendor/libgit2/src/netops.h +2 -2
  158. data/vendor/libgit2/src/notes.c +10 -10
  159. data/vendor/libgit2/src/object.c +22 -14
  160. data/vendor/libgit2/src/odb.c +285 -48
  161. data/vendor/libgit2/src/odb.h +16 -2
  162. data/vendor/libgit2/src/odb_loose.c +28 -18
  163. data/vendor/libgit2/src/odb_mempack.c +1 -1
  164. data/vendor/libgit2/src/odb_pack.c +391 -114
  165. data/vendor/libgit2/src/oid.c +5 -4
  166. data/vendor/libgit2/src/pack-objects.c +54 -48
  167. data/vendor/libgit2/src/pack.c +329 -119
  168. data/vendor/libgit2/src/pack.h +25 -7
  169. data/vendor/libgit2/src/patch.c +14 -7
  170. data/vendor/libgit2/src/patch_generate.c +2 -2
  171. data/vendor/libgit2/src/patch_parse.c +2 -1
  172. data/vendor/libgit2/src/path.c +98 -53
  173. data/vendor/libgit2/src/path.h +79 -6
  174. data/vendor/libgit2/src/pathspec.c +8 -8
  175. data/vendor/libgit2/src/pool.c +13 -7
  176. data/vendor/libgit2/src/posix.c +11 -3
  177. data/vendor/libgit2/src/reader.c +10 -6
  178. data/vendor/libgit2/src/rebase.c +93 -49
  179. data/vendor/libgit2/src/refdb.c +30 -13
  180. data/vendor/libgit2/src/refdb_fs.c +121 -69
  181. data/vendor/libgit2/src/reflog.c +19 -14
  182. data/vendor/libgit2/src/refs.c +76 -41
  183. data/vendor/libgit2/src/refspec.c +32 -12
  184. data/vendor/libgit2/src/remote.c +272 -102
  185. data/vendor/libgit2/src/remote.h +2 -1
  186. data/vendor/libgit2/src/repository.c +176 -103
  187. data/vendor/libgit2/src/repository.h +12 -1
  188. data/vendor/libgit2/src/reset.c +7 -6
  189. data/vendor/libgit2/src/revert.c +6 -2
  190. data/vendor/libgit2/src/revparse.c +14 -9
  191. data/vendor/libgit2/src/revwalk.c +32 -15
  192. data/vendor/libgit2/src/runtime.c +162 -0
  193. data/vendor/libgit2/src/runtime.h +62 -0
  194. data/vendor/libgit2/src/settings.h +11 -0
  195. data/vendor/libgit2/src/signature.c +6 -5
  196. data/vendor/libgit2/src/sortedcache.h +10 -8
  197. data/vendor/libgit2/src/stash.c +3 -1
  198. data/vendor/libgit2/src/status.c +7 -4
  199. data/vendor/libgit2/src/strarray.c +2 -1
  200. data/vendor/libgit2/src/streams/mbedtls.c +14 -17
  201. data/vendor/libgit2/src/streams/mbedtls.h +1 -1
  202. data/vendor/libgit2/src/streams/openssl.c +101 -201
  203. data/vendor/libgit2/src/streams/openssl.h +9 -1
  204. data/vendor/libgit2/src/streams/openssl_dynamic.c +309 -0
  205. data/vendor/libgit2/src/streams/openssl_dynamic.h +348 -0
  206. data/vendor/libgit2/src/streams/openssl_legacy.c +203 -0
  207. data/vendor/libgit2/src/streams/openssl_legacy.h +63 -0
  208. data/vendor/libgit2/src/streams/registry.c +5 -6
  209. data/vendor/libgit2/src/streams/socket.c +6 -2
  210. data/vendor/libgit2/src/streams/stransport.c +6 -3
  211. data/vendor/libgit2/src/streams/tls.c +5 -3
  212. data/vendor/libgit2/src/submodule.c +128 -62
  213. data/vendor/libgit2/src/submodule.h +9 -9
  214. data/vendor/libgit2/src/sysdir.c +4 -6
  215. data/vendor/libgit2/src/tag.c +47 -11
  216. data/vendor/libgit2/src/thread.c +140 -0
  217. data/vendor/libgit2/src/thread.h +479 -0
  218. data/vendor/libgit2/src/threadstate.c +83 -0
  219. data/vendor/libgit2/src/threadstate.h +24 -0
  220. data/vendor/libgit2/src/trace.c +2 -2
  221. data/vendor/libgit2/src/trace.h +17 -13
  222. data/vendor/libgit2/src/transaction.c +19 -8
  223. data/vendor/libgit2/src/transport.c +3 -3
  224. data/vendor/libgit2/src/transports/auth.c +1 -1
  225. data/vendor/libgit2/src/transports/auth_negotiate.c +11 -4
  226. data/vendor/libgit2/src/transports/auth_ntlm.c +10 -6
  227. data/vendor/libgit2/src/transports/credential.c +15 -7
  228. data/vendor/libgit2/src/transports/git.c +1 -3
  229. data/vendor/libgit2/src/transports/http.c +19 -17
  230. data/vendor/libgit2/src/transports/http.h +1 -0
  231. data/vendor/libgit2/src/transports/httpclient.c +53 -26
  232. data/vendor/libgit2/src/transports/httpclient.h +1 -1
  233. data/vendor/libgit2/src/transports/local.c +3 -3
  234. data/vendor/libgit2/src/transports/smart.c +12 -7
  235. data/vendor/libgit2/src/transports/smart.h +1 -1
  236. data/vendor/libgit2/src/transports/smart_protocol.c +11 -5
  237. data/vendor/libgit2/src/transports/ssh.c +51 -17
  238. data/vendor/libgit2/src/transports/winhttp.c +41 -31
  239. data/vendor/libgit2/src/tree.c +100 -77
  240. data/vendor/libgit2/src/tree.h +1 -0
  241. data/vendor/libgit2/src/tsort.c +0 -2
  242. data/vendor/libgit2/src/unix/map.c +3 -1
  243. data/vendor/libgit2/src/unix/pthread.h +2 -1
  244. data/vendor/libgit2/src/utf8.c +150 -0
  245. data/vendor/libgit2/src/utf8.h +52 -0
  246. data/vendor/libgit2/src/util.c +53 -129
  247. data/vendor/libgit2/src/util.h +33 -39
  248. data/vendor/libgit2/src/vector.c +23 -19
  249. data/vendor/libgit2/src/vector.h +4 -2
  250. data/vendor/libgit2/src/win32/findfile.c +4 -2
  251. data/vendor/libgit2/src/win32/map.c +1 -1
  252. data/vendor/libgit2/src/win32/msvc-compat.h +9 -1
  253. data/vendor/libgit2/src/win32/path_w32.c +22 -24
  254. data/vendor/libgit2/src/win32/path_w32.h +0 -1
  255. data/vendor/libgit2/src/win32/posix_w32.c +7 -1
  256. data/vendor/libgit2/src/win32/precompiled.h +0 -1
  257. data/vendor/libgit2/src/win32/reparse.h +4 -4
  258. data/vendor/libgit2/src/win32/thread.c +24 -15
  259. data/vendor/libgit2/src/win32/thread.h +1 -1
  260. data/vendor/libgit2/src/win32/w32_buffer.c +3 -3
  261. data/vendor/libgit2/src/win32/w32_common.h +18 -9
  262. data/vendor/libgit2/src/win32/{w32_crtdbg_stacktrace.c → w32_leakcheck.c} +269 -33
  263. data/vendor/libgit2/src/win32/w32_leakcheck.h +222 -0
  264. data/vendor/libgit2/src/win32/w32_util.h +6 -6
  265. data/vendor/libgit2/src/worktree.c +27 -16
  266. data/vendor/libgit2/src/zstream.c +1 -1
  267. metadata +32 -16
  268. data/vendor/libgit2/src/allocators/win32_crtdbg.c +0 -118
  269. data/vendor/libgit2/src/buf_text.c +0 -316
  270. data/vendor/libgit2/src/buf_text.h +0 -122
  271. data/vendor/libgit2/src/global.c +0 -363
  272. data/vendor/libgit2/src/global.h +0 -41
  273. data/vendor/libgit2/src/thread-utils.c +0 -58
  274. data/vendor/libgit2/src/thread-utils.h +0 -369
  275. data/vendor/libgit2/src/win32/w32_crtdbg_stacktrace.h +0 -127
  276. data/vendor/libgit2/src/win32/w32_stack.c +0 -188
  277. data/vendor/libgit2/src/win32/w32_stack.h +0 -140
@@ -21,6 +21,9 @@ typedef struct git_net_url {
21
21
 
22
22
  #define GIT_NET_URL_INIT { NULL }
23
23
 
24
+ /** Duplicate a URL */
25
+ extern int git_net_url_dup(git_net_url *out, git_net_url *in);
26
+
24
27
  /** Parses a string containing a URL into a structure. */
25
28
  extern int git_net_url_parse(git_net_url *url, const char *str);
26
29
 
@@ -33,8 +36,11 @@ extern int git_net_url_joinpath(
33
36
  /** Ensures that a URL is minimally valid (contains a host, port and path) */
34
37
  extern bool git_net_url_valid(git_net_url *url);
35
38
 
36
- /** Returns nonzero if the URL is on the default port. */
37
- extern int git_net_url_is_default_port(git_net_url *url);
39
+ /** Returns true if the URL is on the default port. */
40
+ extern bool git_net_url_is_default_port(git_net_url *url);
41
+
42
+ /** Returns true if the host portion of the URL is an ipv6 address. */
43
+ extern bool git_net_url_is_ipv6(git_net_url *url);
38
44
 
39
45
  /* Applies a redirect to the URL with a git-aware service suffix. */
40
46
  extern int git_net_url_apply_redirect(
@@ -51,6 +57,14 @@ extern int git_net_url_fmt(git_buf *out, git_net_url *url);
51
57
  /** Place the path and query string into the given buffer. */
52
58
  extern int git_net_url_fmt_path(git_buf *buf, git_net_url *url);
53
59
 
60
+ /** Determines if the url matches given pattern or pattern list */
61
+ extern bool git_net_url_matches_pattern(
62
+ git_net_url *url,
63
+ const char *pattern);
64
+ extern bool git_net_url_matches_pattern_list(
65
+ git_net_url *url,
66
+ const char *pattern_list);
67
+
54
68
  /** Disposes the contents of the structure. */
55
69
  extern void git_net_url_dispose(git_net_url *url);
56
70
 
@@ -13,7 +13,7 @@
13
13
  #include "posix.h"
14
14
  #include "buffer.h"
15
15
  #include "http_parser.h"
16
- #include "global.h"
16
+ #include "runtime.h"
17
17
 
18
18
  int gitno_recv(gitno_buffer *buf)
19
19
  {
@@ -61,18 +61,20 @@ void gitno_buffer_setup_fromstream(git_stream *st, gitno_buffer *buf, char *data
61
61
  }
62
62
 
63
63
  /* Consume up to ptr and move the rest of the buffer to the beginning */
64
- void gitno_consume(gitno_buffer *buf, const char *ptr)
64
+ int gitno_consume(gitno_buffer *buf, const char *ptr)
65
65
  {
66
66
  size_t consumed;
67
67
 
68
- assert(ptr - buf->data >= 0);
69
- assert(ptr - buf->data <= (int) buf->len);
68
+ GIT_ASSERT(ptr - buf->data >= 0);
69
+ GIT_ASSERT(ptr - buf->data <= (int) buf->len);
70
70
 
71
71
  consumed = ptr - buf->data;
72
72
 
73
73
  memmove(buf->data, ptr, buf->offset - consumed);
74
74
  memset(buf->data + buf->offset, 0x0, buf->len - buf->offset);
75
75
  buf->offset -= consumed;
76
+
77
+ return 0;
76
78
  }
77
79
 
78
80
  /* Consume const bytes and move the rest of the buffer to the beginning */
@@ -14,7 +14,7 @@
14
14
  #include "net.h"
15
15
 
16
16
  #ifdef GIT_OPENSSL
17
- # include <openssl/ssl.h>
17
+ # include "streams/openssl.h"
18
18
  #endif
19
19
 
20
20
  typedef struct gitno_ssl {
@@ -62,7 +62,7 @@ void gitno_buffer_setup_fromstream(git_stream *st, gitno_buffer *buf, char *data
62
62
  void gitno_buffer_setup_callback(gitno_buffer *buf, char *data, size_t len, int (*recv)(gitno_buffer *buf), void *cb_data);
63
63
  int gitno_recv(gitno_buffer *buf);
64
64
 
65
- void gitno_consume(gitno_buffer *buf, const char *ptr);
65
+ int gitno_consume(gitno_buffer *buf, const char *ptr);
66
66
  void gitno_consume_n(gitno_buffer *buf, size_t cons);
67
67
 
68
68
  #endif
@@ -627,11 +627,11 @@ int git_note_default_ref(git_buf *out, git_repository *repo)
627
627
  char *default_ref;
628
628
  int error;
629
629
 
630
- assert(out && repo);
630
+ GIT_ASSERT_ARG(out);
631
+ GIT_ASSERT_ARG(repo);
631
632
 
632
- git_buf_sanitize(out);
633
-
634
- if ((error = note_get_default_ref(&default_ref, repo)) < 0)
633
+ if ((error = git_buf_sanitize(out)) < 0 ||
634
+ (error = note_get_default_ref(&default_ref, repo)) < 0)
635
635
  return error;
636
636
 
637
637
  git_buf_attach(out, default_ref, strlen(default_ref));
@@ -640,25 +640,25 @@ int git_note_default_ref(git_buf *out, git_repository *repo)
640
640
 
641
641
  const git_signature *git_note_committer(const git_note *note)
642
642
  {
643
- assert(note);
643
+ GIT_ASSERT_ARG_WITH_RETVAL(note, NULL);
644
644
  return note->committer;
645
645
  }
646
646
 
647
647
  const git_signature *git_note_author(const git_note *note)
648
648
  {
649
- assert(note);
649
+ GIT_ASSERT_ARG_WITH_RETVAL(note, NULL);
650
650
  return note->author;
651
651
  }
652
652
 
653
- const char * git_note_message(const git_note *note)
653
+ const char *git_note_message(const git_note *note)
654
654
  {
655
- assert(note);
655
+ GIT_ASSERT_ARG_WITH_RETVAL(note, NULL);
656
656
  return note->message;
657
657
  }
658
658
 
659
- const git_oid * git_note_id(const git_note *note)
659
+ const git_oid *git_note_id(const git_note *note)
660
660
  {
661
- assert(note);
661
+ GIT_ASSERT_ARG_WITH_RETVAL(note, NULL);
662
662
  return &note->id;
663
663
  }
664
664
 
@@ -67,7 +67,7 @@ int git_object__from_raw(
67
67
  size_t object_size;
68
68
  int error;
69
69
 
70
- assert(object_out);
70
+ GIT_ASSERT_ARG(object_out);
71
71
  *object_out = NULL;
72
72
 
73
73
  /* Validate type match */
@@ -91,7 +91,7 @@ int git_object__from_raw(
91
91
 
92
92
  /* Parse raw object data */
93
93
  def = &git_objects_table[type];
94
- assert(def->free && def->parse_raw);
94
+ GIT_ASSERT(def->free && def->parse_raw);
95
95
 
96
96
  if ((error = def->parse_raw(object, data, size)) < 0) {
97
97
  def->free(object);
@@ -115,7 +115,7 @@ int git_object__from_odb_object(
115
115
  git_object_def *def;
116
116
  git_object *object = NULL;
117
117
 
118
- assert(object_out);
118
+ GIT_ASSERT_ARG(object_out);
119
119
  *object_out = NULL;
120
120
 
121
121
  /* Validate type match */
@@ -141,7 +141,7 @@ int git_object__from_odb_object(
141
141
 
142
142
  /* Parse raw object data */
143
143
  def = &git_objects_table[odb_obj->cached.type];
144
- assert(def->free && def->parse);
144
+ GIT_ASSERT(def->free && def->parse);
145
145
 
146
146
  if ((error = def->parse(object, odb_obj)) < 0)
147
147
  def->free(object);
@@ -174,7 +174,9 @@ int git_object_lookup_prefix(
174
174
  git_odb_object *odb_obj = NULL;
175
175
  int error = 0;
176
176
 
177
- assert(repo && object_out && id);
177
+ GIT_ASSERT_ARG(repo);
178
+ GIT_ASSERT_ARG(object_out);
179
+ GIT_ASSERT_ARG(id);
178
180
 
179
181
  if (len < GIT_OID_MINPREFIXLEN) {
180
182
  git_error_set(GIT_ERROR_OBJECT, "ambiguous lookup - OID prefix is too short");
@@ -211,7 +213,7 @@ int git_object_lookup_prefix(
211
213
  } else if (cached->flags == GIT_CACHE_STORE_RAW) {
212
214
  odb_obj = (git_odb_object *)cached;
213
215
  } else {
214
- assert(!"Wrong caching type in the global object cache");
216
+ GIT_ASSERT(!"Wrong caching type in the global object cache");
215
217
  }
216
218
  } else {
217
219
  /* Object was not found in the cache, let's explore the backends.
@@ -263,19 +265,19 @@ void git_object_free(git_object *object)
263
265
 
264
266
  const git_oid *git_object_id(const git_object *obj)
265
267
  {
266
- assert(obj);
268
+ GIT_ASSERT_ARG_WITH_RETVAL(obj, NULL);
267
269
  return &obj->cached.oid;
268
270
  }
269
271
 
270
272
  git_object_t git_object_type(const git_object *obj)
271
273
  {
272
- assert(obj);
274
+ GIT_ASSERT_ARG_WITH_RETVAL(obj, GIT_OBJECT_INVALID);
273
275
  return obj->cached.type;
274
276
  }
275
277
 
276
278
  git_repository *git_object_owner(const git_object *obj)
277
279
  {
278
- assert(obj);
280
+ GIT_ASSERT_ARG_WITH_RETVAL(obj, NULL);
279
281
  return obj->repo;
280
282
  }
281
283
 
@@ -396,9 +398,10 @@ int git_object_peel(
396
398
  git_object *source, *deref = NULL;
397
399
  int error;
398
400
 
399
- assert(object && peeled);
401
+ GIT_ASSERT_ARG(object);
402
+ GIT_ASSERT_ARG(peeled);
400
403
 
401
- assert(target_type == GIT_OBJECT_TAG ||
404
+ GIT_ASSERT_ARG(target_type == GIT_OBJECT_TAG ||
402
405
  target_type == GIT_OBJECT_COMMIT ||
403
406
  target_type == GIT_OBJECT_TREE ||
404
407
  target_type == GIT_OBJECT_BLOB ||
@@ -461,7 +464,9 @@ int git_object_lookup_bypath(
461
464
  git_tree *tree = NULL;
462
465
  git_tree_entry *entry = NULL;
463
466
 
464
- assert(out && treeish && path);
467
+ GIT_ASSERT_ARG(out);
468
+ GIT_ASSERT_ARG(treeish);
469
+ GIT_ASSERT_ARG(path);
465
470
 
466
471
  if ((error = git_object_peel((git_object**)&tree, treeish, GIT_OBJECT_TREE)) < 0 ||
467
472
  (error = git_tree_entry_bypath(&entry, tree, path)) < 0)
@@ -493,9 +498,12 @@ int git_object_short_id(git_buf *out, const git_object *obj)
493
498
  git_oid id = {{0}};
494
499
  git_odb *odb;
495
500
 
496
- assert(out && obj);
501
+ GIT_ASSERT_ARG(out);
502
+ GIT_ASSERT_ARG(obj);
503
+
504
+ if ((error = git_buf_sanitize(out)) < 0)
505
+ return error;
497
506
 
498
- git_buf_sanitize(out);
499
507
  repo = git_object_owner(obj);
500
508
 
501
509
  if ((error = git_repository__configmap_lookup(&len, repo, GIT_CONFIGMAP_ABBREV)) < 0)
@@ -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);
@@ -347,7 +346,7 @@ int git_odb_hash(git_oid *id, const void *data, size_t len, git_object_t type)
347
346
  {
348
347
  git_rawobj raw;
349
348
 
350
- assert(id);
349
+ GIT_ASSERT_ARG(id);
351
350
 
352
351
  raw.data = (void *)data;
353
352
  raw.len = len;
@@ -377,7 +376,7 @@ static int fake_wstream__write(git_odb_stream *_stream, const char *data, size_t
377
376
  {
378
377
  fake_wstream *stream = (fake_wstream *)_stream;
379
378
 
380
- assert(stream->written + len <= stream->size);
379
+ GIT_ASSERT(stream->written + len <= stream->size);
381
380
 
382
381
  memcpy(stream->buffer + stream->written, data, len);
383
382
  stream->written += len;
@@ -450,12 +449,18 @@ int git_odb_new(git_odb **out)
450
449
  git_odb *db = git__calloc(1, sizeof(*db));
451
450
  GIT_ERROR_CHECK_ALLOC(db);
452
451
 
452
+ if (git_mutex_init(&db->lock) < 0) {
453
+ git__free(db);
454
+ return -1;
455
+ }
453
456
  if (git_cache_init(&db->own_cache) < 0) {
457
+ git_mutex_free(&db->lock);
454
458
  git__free(db);
455
459
  return -1;
456
460
  }
457
461
  if (git_vector_init(&db->backends, 4, backend_sort_cmp) < 0) {
458
462
  git_cache_dispose(&db->own_cache);
463
+ git_mutex_free(&db->lock);
459
464
  git__free(db);
460
465
  return -1;
461
466
  }
@@ -471,12 +476,13 @@ static int add_backend_internal(
471
476
  {
472
477
  backend_internal *internal;
473
478
 
474
- assert(odb && backend);
479
+ GIT_ASSERT_ARG(odb);
480
+ GIT_ASSERT_ARG(backend);
475
481
 
476
482
  GIT_ERROR_CHECK_VERSION(backend, GIT_ODB_BACKEND_VERSION, "git_odb_backend");
477
483
 
478
484
  /* Check if the backend is already owned by another ODB */
479
- assert(!backend->odb || backend->odb == odb);
485
+ GIT_ASSERT(!backend->odb || backend->odb == odb);
480
486
 
481
487
  internal = git__malloc(sizeof(backend_internal));
482
488
  GIT_ERROR_CHECK_ALLOC(internal);
@@ -486,13 +492,18 @@ static int add_backend_internal(
486
492
  internal->is_alternate = is_alternate;
487
493
  internal->disk_inode = disk_inode;
488
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
+ }
489
499
  if (git_vector_insert(&odb->backends, internal) < 0) {
500
+ git_mutex_unlock(&odb->lock);
490
501
  git__free(internal);
491
502
  return -1;
492
503
  }
493
-
494
504
  git_vector_sort(&odb->backends);
495
505
  internal->backend->odb = odb;
506
+ git_mutex_unlock(&odb->lock);
496
507
  return 0;
497
508
  }
498
509
 
@@ -508,8 +519,19 @@ int git_odb_add_alternate(git_odb *odb, git_odb_backend *backend, int priority)
508
519
 
509
520
  size_t git_odb_num_backends(git_odb *odb)
510
521
  {
511
- assert(odb);
512
- 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;
513
535
  }
514
536
 
515
537
  static int git_odb__error_unsupported_in_backend(const char *action)
@@ -523,24 +545,35 @@ static int git_odb__error_unsupported_in_backend(const char *action)
523
545
  int git_odb_get_backend(git_odb_backend **out, git_odb *odb, size_t pos)
524
546
  {
525
547
  backend_internal *internal;
548
+ int error;
549
+
550
+ GIT_ASSERT_ARG(out);
551
+ GIT_ASSERT_ARG(odb);
526
552
 
527
- 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
+ }
528
558
  internal = git_vector_get(&odb->backends, pos);
529
559
 
530
- if (internal && internal->backend) {
531
- *out = internal->backend;
532
- 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;
533
565
  }
566
+ *out = internal->backend;
567
+ git_mutex_unlock(&odb->lock);
534
568
 
535
- git_error_set(GIT_ERROR_ODB, "no ODB backend loaded at index %" PRIuZ, pos);
536
- return GIT_ENOTFOUND;
569
+ return 0;
537
570
  }
538
571
 
539
572
  int git_odb__add_default_backends(
540
573
  git_odb *db, const char *objects_dir,
541
574
  bool as_alternates, int alternate_depth)
542
575
  {
543
- size_t i;
576
+ size_t i = 0;
544
577
  struct stat st;
545
578
  ino_t inode;
546
579
  git_odb_backend *loose, *packed;
@@ -549,7 +582,7 @@ int git_odb__add_default_backends(
549
582
  * a cross-platform workaround for this */
550
583
  #ifdef GIT_WIN32
551
584
  GIT_UNUSED(i);
552
- GIT_UNUSED(st);
585
+ GIT_UNUSED(&st);
553
586
 
554
587
  inode = 0;
555
588
  #else
@@ -564,23 +597,40 @@ int git_odb__add_default_backends(
564
597
 
565
598
  inode = st.st_ino;
566
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
+ }
567
604
  for (i = 0; i < db->backends.length; ++i) {
568
605
  backend_internal *backend = git_vector_get(&db->backends, i);
569
- if (backend->disk_inode == inode)
606
+ if (backend->disk_inode == inode) {
607
+ git_mutex_unlock(&db->lock);
570
608
  return 0;
609
+ }
571
610
  }
611
+ git_mutex_unlock(&db->lock);
572
612
  #endif
573
613
 
574
614
  /* add the loose object backend */
575
615
  if (git_odb_backend_loose(&loose, objects_dir, -1, db->do_fsync, 0, 0) < 0 ||
576
- 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)
577
617
  return -1;
578
618
 
579
619
  /* add the packed file backend */
580
620
  if (git_odb_backend_pack(&packed, objects_dir) < 0 ||
581
- 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)
582
622
  return -1;
583
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
+
584
634
  return load_alternates(db, objects_dir, alternate_depth);
585
635
  }
586
636
 
@@ -642,11 +692,29 @@ int git_odb_add_disk_alternate(git_odb *odb, const char *path)
642
692
  return git_odb__add_default_backends(odb, path, true, 0);
643
693
  }
644
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
+
645
712
  int git_odb_open(git_odb **out, const char *objects_dir)
646
713
  {
647
714
  git_odb *db;
648
715
 
649
- assert(out && objects_dir);
716
+ GIT_ASSERT_ARG(out);
717
+ GIT_ASSERT_ARG(objects_dir);
650
718
 
651
719
  *out = NULL;
652
720
 
@@ -683,7 +751,12 @@ int git_odb__set_caps(git_odb *odb, int caps)
683
751
  static void odb_free(git_odb *db)
684
752
  {
685
753
  size_t i;
754
+ bool locked = true;
686
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
+ }
687
760
  for (i = 0; i < db->backends.length; ++i) {
688
761
  backend_internal *internal = git_vector_get(&db->backends, i);
689
762
  git_odb_backend *backend = internal->backend;
@@ -692,9 +765,13 @@ static void odb_free(git_odb *db)
692
765
 
693
766
  git__free(internal);
694
767
  }
768
+ if (locked)
769
+ git_mutex_unlock(&db->lock);
695
770
 
771
+ git_commit_graph_free(db->cgraph);
696
772
  git_vector_free(&db->backends);
697
773
  git_cache_dispose(&db->own_cache);
774
+ git_mutex_free(&db->lock);
698
775
 
699
776
  git__memzero(db, sizeof(*db));
700
777
  git__free(db);
@@ -715,7 +792,12 @@ static int odb_exists_1(
715
792
  {
716
793
  size_t i;
717
794
  bool found = false;
795
+ int error;
718
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
+ }
719
801
  for (i = 0; i < db->backends.length && !found; ++i) {
720
802
  backend_internal *internal = git_vector_get(&db->backends, i);
721
803
  git_odb_backend *b = internal->backend;
@@ -726,10 +808,34 @@ static int odb_exists_1(
726
808
  if (b->exists != NULL)
727
809
  found = (bool)b->exists(b, id);
728
810
  }
811
+ git_mutex_unlock(&db->lock);
729
812
 
730
813
  return (int)found;
731
814
  }
732
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
+
733
839
  static int odb_freshen_1(
734
840
  git_odb *db,
735
841
  const git_oid *id,
@@ -737,7 +843,12 @@ static int odb_freshen_1(
737
843
  {
738
844
  size_t i;
739
845
  bool found = false;
846
+ int error;
740
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
+ }
741
852
  for (i = 0; i < db->backends.length && !found; ++i) {
742
853
  backend_internal *internal = git_vector_get(&db->backends, i);
743
854
  git_odb_backend *b = internal->backend;
@@ -750,13 +861,15 @@ static int odb_freshen_1(
750
861
  else if (b->exists != NULL)
751
862
  found = b->exists(b, id);
752
863
  }
864
+ git_mutex_unlock(&db->lock);
753
865
 
754
866
  return (int)found;
755
867
  }
756
868
 
757
869
  int git_odb__freshen(git_odb *db, const git_oid *id)
758
870
  {
759
- assert(db && id);
871
+ GIT_ASSERT_ARG(db);
872
+ GIT_ASSERT_ARG(id);
760
873
 
761
874
  if (odb_freshen_1(db, id, false))
762
875
  return 1;
@@ -772,7 +885,8 @@ int git_odb_exists(git_odb *db, const git_oid *id)
772
885
  {
773
886
  git_odb_object *object;
774
887
 
775
- assert(db && id);
888
+ GIT_ASSERT_ARG(db);
889
+ GIT_ASSERT_ARG(id);
776
890
 
777
891
  if (git_oid_is_zero(id))
778
892
  return 0;
@@ -799,6 +913,11 @@ static int odb_exists_prefix_1(git_oid *out, git_odb *db,
799
913
  int error = GIT_ENOTFOUND, num_found = 0;
800
914
  git_oid last_found = {{0}}, found;
801
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;
802
921
  for (i = 0; i < db->backends.length; ++i) {
803
922
  backend_internal *internal = git_vector_get(&db->backends, i);
804
923
  git_odb_backend *b = internal->backend;
@@ -812,18 +931,23 @@ static int odb_exists_prefix_1(git_oid *out, git_odb *db,
812
931
  error = b->exists_prefix(&found, b, key, len);
813
932
  if (error == GIT_ENOTFOUND || error == GIT_PASSTHROUGH)
814
933
  continue;
815
- if (error)
934
+ if (error) {
935
+ git_mutex_unlock(&db->lock);
816
936
  return error;
937
+ }
817
938
 
818
939
  /* make sure found item doesn't introduce ambiguity */
819
940
  if (num_found) {
820
- if (git_oid__cmp(&last_found, &found))
941
+ if (git_oid__cmp(&last_found, &found)) {
942
+ git_mutex_unlock(&db->lock);
821
943
  return git_odb__error_ambiguous("multiple matches for prefix");
944
+ }
822
945
  } else {
823
946
  git_oid_cpy(&last_found, &found);
824
947
  num_found++;
825
948
  }
826
949
  }
950
+ git_mutex_unlock(&db->lock);
827
951
 
828
952
  if (!num_found)
829
953
  return GIT_ENOTFOUND;
@@ -840,7 +964,8 @@ int git_odb_exists_prefix(
840
964
  int error;
841
965
  git_oid key = {{0}};
842
966
 
843
- assert(db && short_id);
967
+ GIT_ASSERT_ARG(db);
968
+ GIT_ASSERT_ARG(short_id);
844
969
 
845
970
  if (len < GIT_OID_MINPREFIXLEN)
846
971
  return git_odb__error_ambiguous("prefix length too short");
@@ -876,7 +1001,8 @@ int git_odb_expand_ids(
876
1001
  {
877
1002
  size_t i;
878
1003
 
879
- assert(db && ids);
1004
+ GIT_ASSERT_ARG(db);
1005
+ GIT_ASSERT_ARG(ids);
880
1006
 
881
1007
  for (i = 0; i < count; i++) {
882
1008
  git_odb_expand_id *query = &ids[i];
@@ -963,6 +1089,10 @@ static int odb_read_header_1(
963
1089
  return 0;
964
1090
  }
965
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
+ }
966
1096
  for (i = 0; i < db->backends.length; ++i) {
967
1097
  backend_internal *internal = git_vector_get(&db->backends, i);
968
1098
  git_odb_backend *b = internal->backend;
@@ -984,9 +1114,11 @@ static int odb_read_header_1(
984
1114
  case GIT_ENOTFOUND:
985
1115
  break;
986
1116
  default:
1117
+ git_mutex_unlock(&db->lock);
987
1118
  return error;
988
1119
  }
989
1120
  }
1121
+ git_mutex_unlock(&db->lock);
990
1122
 
991
1123
  return passthrough ? GIT_PASSTHROUGH : GIT_ENOTFOUND;
992
1124
  }
@@ -998,7 +1130,11 @@ int git_odb__read_header_or_object(
998
1130
  int error = GIT_ENOTFOUND;
999
1131
  git_odb_object *object;
1000
1132
 
1001
- 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);
1002
1138
 
1003
1139
  *out = NULL;
1004
1140
 
@@ -1055,6 +1191,10 @@ static int odb_read_1(git_odb_object **out, git_odb *db, const git_oid *id,
1055
1191
  return error;
1056
1192
  }
1057
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
+ }
1058
1198
  for (i = 0; i < db->backends.length && !found; ++i) {
1059
1199
  backend_internal *internal = git_vector_get(&db->backends, i);
1060
1200
  git_odb_backend *b = internal->backend;
@@ -1067,12 +1207,15 @@ static int odb_read_1(git_odb_object **out, git_odb *db, const git_oid *id,
1067
1207
  if (error == GIT_PASSTHROUGH || error == GIT_ENOTFOUND)
1068
1208
  continue;
1069
1209
 
1070
- if (error < 0)
1210
+ if (error < 0) {
1211
+ git_mutex_unlock(&db->lock);
1071
1212
  return error;
1213
+ }
1072
1214
 
1073
1215
  found = true;
1074
1216
  }
1075
1217
  }
1218
+ git_mutex_unlock(&db->lock);
1076
1219
 
1077
1220
  if (!found)
1078
1221
  return GIT_ENOTFOUND;
@@ -1105,7 +1248,9 @@ int git_odb_read(git_odb_object **out, git_odb *db, const git_oid *id)
1105
1248
  {
1106
1249
  int error;
1107
1250
 
1108
- assert(out && db && id);
1251
+ GIT_ASSERT_ARG(out);
1252
+ GIT_ASSERT_ARG(db);
1253
+ GIT_ASSERT_ARG(id);
1109
1254
 
1110
1255
  if (git_oid_is_zero(id))
1111
1256
  return error_null_oid(GIT_ENOTFOUND, "cannot read object");
@@ -1163,6 +1308,10 @@ static int read_prefix_1(git_odb_object **out, git_odb *db,
1163
1308
  bool found = false;
1164
1309
  git_odb_object *object;
1165
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
+ }
1166
1315
  for (i = 0; i < db->backends.length; ++i) {
1167
1316
  backend_internal *internal = git_vector_get(&db->backends, i);
1168
1317
  git_odb_backend *b = internal->backend;
@@ -1179,8 +1328,10 @@ static int read_prefix_1(git_odb_object **out, git_odb *db,
1179
1328
  continue;
1180
1329
  }
1181
1330
 
1182
- if (error)
1331
+ if (error) {
1332
+ git_mutex_unlock(&db->lock);
1183
1333
  goto out;
1334
+ }
1184
1335
 
1185
1336
  git__free(data);
1186
1337
  data = raw.data;
@@ -1195,6 +1346,7 @@ static int read_prefix_1(git_odb_object **out, git_odb *db,
1195
1346
 
1196
1347
  error = git_odb__error_ambiguous(buf.ptr);
1197
1348
  git_buf_dispose(&buf);
1349
+ git_mutex_unlock(&db->lock);
1198
1350
  goto out;
1199
1351
  }
1200
1352
 
@@ -1202,6 +1354,7 @@ static int read_prefix_1(git_odb_object **out, git_odb *db,
1202
1354
  found = true;
1203
1355
  }
1204
1356
  }
1357
+ git_mutex_unlock(&db->lock);
1205
1358
 
1206
1359
  if (!found)
1207
1360
  return GIT_ENOTFOUND;
@@ -1238,7 +1391,8 @@ int git_odb_read_prefix(
1238
1391
  git_oid key = {{0}};
1239
1392
  int error;
1240
1393
 
1241
- assert(out && db);
1394
+ GIT_ASSERT_ARG(out);
1395
+ GIT_ASSERT_ARG(db);
1242
1396
 
1243
1397
  if (len < GIT_OID_MINPREFIXLEN)
1244
1398
  return git_odb__error_ambiguous("prefix length too short");
@@ -1268,16 +1422,32 @@ int git_odb_read_prefix(
1268
1422
  int git_odb_foreach(git_odb *db, git_odb_foreach_cb cb, void *payload)
1269
1423
  {
1270
1424
  unsigned int i;
1425
+ git_vector backends = GIT_VECTOR_INIT;
1271
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;
1272
1439
 
1273
- git_vector_foreach(&db->backends, i, internal) {
1440
+ git_vector_foreach(&backends, i, internal) {
1274
1441
  git_odb_backend *b = internal->backend;
1275
- int error = b->foreach(b, cb, payload);
1442
+ error = b->foreach(b, cb, payload);
1276
1443
  if (error != 0)
1277
- return error;
1444
+ goto cleanup;
1278
1445
  }
1279
1446
 
1280
- return 0;
1447
+ cleanup:
1448
+ git_vector_free(&backends);
1449
+
1450
+ return error;
1281
1451
  }
1282
1452
 
1283
1453
  int git_odb_write(
@@ -1287,7 +1457,8 @@ int git_odb_write(
1287
1457
  int error;
1288
1458
  git_odb_stream *stream;
1289
1459
 
1290
- assert(oid && db);
1460
+ GIT_ASSERT_ARG(oid);
1461
+ GIT_ASSERT_ARG(db);
1291
1462
 
1292
1463
  if ((error = git_odb_hash(oid, data, len, type)) < 0)
1293
1464
  return error;
@@ -1298,6 +1469,10 @@ int git_odb_write(
1298
1469
  if (git_odb__freshen(db, oid))
1299
1470
  return 0;
1300
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
+ }
1301
1476
  for (i = 0, error = GIT_ERROR; i < db->backends.length && error < 0; ++i) {
1302
1477
  backend_internal *internal = git_vector_get(&db->backends, i);
1303
1478
  git_odb_backend *b = internal->backend;
@@ -1309,6 +1484,7 @@ int git_odb_write(
1309
1484
  if (b->write != NULL)
1310
1485
  error = b->write(b, oid, data, len, type);
1311
1486
  }
1487
+ git_mutex_unlock(&db->lock);
1312
1488
 
1313
1489
  if (!error || error == GIT_PASSTHROUGH)
1314
1490
  return 0;
@@ -1347,8 +1523,14 @@ int git_odb_open_wstream(
1347
1523
  int error = GIT_ERROR;
1348
1524
  git_hash_ctx *ctx = NULL;
1349
1525
 
1350
- assert(stream && db);
1526
+ GIT_ASSERT_ARG(stream);
1527
+ GIT_ASSERT_ARG(db);
1351
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;
1352
1534
  for (i = 0; i < db->backends.length && error < 0; ++i) {
1353
1535
  backend_internal *internal = git_vector_get(&db->backends, i);
1354
1536
  git_odb_backend *b = internal->backend;
@@ -1365,6 +1547,7 @@ int git_odb_open_wstream(
1365
1547
  error = init_fake_wstream(stream, b, size, type);
1366
1548
  }
1367
1549
  }
1550
+ git_mutex_unlock(&db->lock);
1368
1551
 
1369
1552
  if (error < 0) {
1370
1553
  if (error == GIT_PASSTHROUGH)
@@ -1457,8 +1640,14 @@ int git_odb_open_rstream(
1457
1640
  size_t i, reads = 0;
1458
1641
  int error = GIT_ERROR;
1459
1642
 
1460
- assert(stream && db);
1643
+ GIT_ASSERT_ARG(stream);
1644
+ GIT_ASSERT_ARG(db);
1461
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;
1462
1651
  for (i = 0; i < db->backends.length && error < 0; ++i) {
1463
1652
  backend_internal *internal = git_vector_get(&db->backends, i);
1464
1653
  git_odb_backend *b = internal->backend;
@@ -1468,6 +1657,7 @@ int git_odb_open_rstream(
1468
1657
  error = b->readstream(stream, len, type, b, oid);
1469
1658
  }
1470
1659
  }
1660
+ git_mutex_unlock(&db->lock);
1471
1661
 
1472
1662
  if (error == GIT_PASSTHROUGH)
1473
1663
  error = 0;
@@ -1482,8 +1672,14 @@ int git_odb_write_pack(struct git_odb_writepack **out, git_odb *db, git_indexer_
1482
1672
  size_t i, writes = 0;
1483
1673
  int error = GIT_ERROR;
1484
1674
 
1485
- assert(out && db);
1675
+ GIT_ASSERT_ARG(out);
1676
+ GIT_ASSERT_ARG(db);
1486
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;
1487
1683
  for (i = 0; i < db->backends.length && error < 0; ++i) {
1488
1684
  backend_internal *internal = git_vector_get(&db->backends, i);
1489
1685
  git_odb_backend *b = internal->backend;
@@ -1497,6 +1693,7 @@ int git_odb_write_pack(struct git_odb_writepack **out, git_odb *db, git_indexer_
1497
1693
  error = b->writepack(out, b, db, progress_cb, progress_payload);
1498
1694
  }
1499
1695
  }
1696
+ git_mutex_unlock(&db->lock);
1500
1697
 
1501
1698
  if (error == GIT_PASSTHROUGH)
1502
1699
  error = 0;
@@ -1506,6 +1703,35 @@ int git_odb_write_pack(struct git_odb_writepack **out, git_odb *db, git_indexer_
1506
1703
  return error;
1507
1704
  }
1508
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
+
1509
1735
  void *git_odb_backend_data_alloc(git_odb_backend *backend, size_t len)
1510
1736
  {
1511
1737
  GIT_UNUSED(backend);
@@ -1528,18 +1754,29 @@ void git_odb_backend_data_free(git_odb_backend *backend, void *data)
1528
1754
  int git_odb_refresh(struct git_odb *db)
1529
1755
  {
1530
1756
  size_t i;
1531
- assert(db);
1757
+ int error;
1758
+
1759
+ GIT_ASSERT_ARG(db);
1532
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
+ }
1533
1765
  for (i = 0; i < db->backends.length; ++i) {
1534
1766
  backend_internal *internal = git_vector_get(&db->backends, i);
1535
1767
  git_odb_backend *b = internal->backend;
1536
1768
 
1537
1769
  if (b->refresh != NULL) {
1538
1770
  int error = b->refresh(b);
1539
- if (error < 0)
1771
+ if (error < 0) {
1772
+ git_mutex_unlock(&db->lock);
1540
1773
  return error;
1774
+ }
1541
1775
  }
1542
1776
  }
1777
+ if (db->cgraph)
1778
+ git_commit_graph_refresh(db->cgraph);
1779
+ git_mutex_unlock(&db->lock);
1543
1780
 
1544
1781
  return 0;
1545
1782
  }