rugged 1.1.1 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
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
  }