rugged 1.0.0 → 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 (338) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +1 -0
  3. data/README.md +3 -3
  4. data/ext/rugged/rugged.c +7 -4
  5. data/ext/rugged/rugged_commit.c +1 -1
  6. data/ext/rugged/rugged_config.c +1 -1
  7. data/ext/rugged/rugged_object.c +1 -1
  8. data/ext/rugged/rugged_remote.c +32 -2
  9. data/ext/rugged/rugged_repo.c +13 -3
  10. data/lib/rugged/commit.rb +17 -4
  11. data/lib/rugged/repository.rb +7 -8
  12. data/lib/rugged/submodule_collection.rb +4 -4
  13. data/lib/rugged/version.rb +1 -1
  14. data/vendor/libgit2/CMakeLists.txt +41 -74
  15. data/vendor/libgit2/COPYING +109 -1
  16. data/vendor/libgit2/cmake/{Modules/AddCFlagIfSupported.cmake → AddCFlagIfSupported.cmake} +0 -0
  17. data/vendor/libgit2/cmake/{Modules/EnableWarnings.cmake → EnableWarnings.cmake} +0 -0
  18. data/vendor/libgit2/cmake/{Modules/FindCoreFoundation.cmake → FindCoreFoundation.cmake} +0 -0
  19. data/vendor/libgit2/cmake/{Modules/FindGSSAPI.cmake → FindGSSAPI.cmake} +0 -0
  20. data/vendor/libgit2/cmake/{Modules/FindGSSFramework.cmake → FindGSSFramework.cmake} +0 -0
  21. data/vendor/libgit2/cmake/{Modules/FindHTTP_Parser.cmake → FindHTTP_Parser.cmake} +0 -0
  22. data/vendor/libgit2/cmake/{Modules/FindIconv.cmake → FindIconv.cmake} +0 -0
  23. data/vendor/libgit2/cmake/{Modules/FindPCRE.cmake → FindPCRE.cmake} +0 -0
  24. data/vendor/libgit2/cmake/{Modules/FindPCRE2.cmake → FindPCRE2.cmake} +0 -0
  25. data/vendor/libgit2/cmake/{Modules/FindPkgLibraries.cmake → FindPkgLibraries.cmake} +0 -0
  26. data/vendor/libgit2/cmake/{Modules/FindSecurity.cmake → FindSecurity.cmake} +0 -0
  27. data/vendor/libgit2/cmake/{Modules/FindStatNsec.cmake → FindStatNsec.cmake} +0 -0
  28. data/vendor/libgit2/cmake/Findfutimens.cmake +14 -0
  29. data/vendor/libgit2/cmake/{Modules/FindmbedTLS.cmake → FindmbedTLS.cmake} +0 -0
  30. data/vendor/libgit2/cmake/{Modules/IdeSplitSources.cmake → IdeSplitSources.cmake} +0 -0
  31. data/vendor/libgit2/cmake/{Modules/PkgBuildConfig.cmake → PkgBuildConfig.cmake} +0 -0
  32. data/vendor/libgit2/cmake/{Modules/SanitizeBool.cmake → SanitizeBool.cmake} +0 -0
  33. data/vendor/libgit2/cmake/{Modules/SelectGSSAPI.cmake → SelectGSSAPI.cmake} +18 -26
  34. data/vendor/libgit2/cmake/{Modules/SelectHTTPSBackend.cmake → SelectHTTPSBackend.cmake} +29 -32
  35. data/vendor/libgit2/cmake/{Modules/SelectHashes.cmake → SelectHashes.cmake} +21 -28
  36. data/vendor/libgit2/deps/chromium-zlib/CMakeLists.txt +101 -0
  37. data/vendor/libgit2/deps/http-parser/CMakeLists.txt +4 -3
  38. data/vendor/libgit2/deps/ntlmclient/CMakeLists.txt +24 -10
  39. data/vendor/libgit2/deps/ntlmclient/compat.h +0 -27
  40. data/vendor/libgit2/deps/ntlmclient/crypt.h +14 -9
  41. data/vendor/libgit2/deps/ntlmclient/crypt_commoncrypto.c +20 -20
  42. data/vendor/libgit2/deps/ntlmclient/crypt_commoncrypto.h +3 -3
  43. data/vendor/libgit2/deps/ntlmclient/crypt_mbedtls.c +37 -36
  44. data/vendor/libgit2/deps/ntlmclient/crypt_mbedtls.h +4 -3
  45. data/vendor/libgit2/deps/ntlmclient/crypt_openssl.c +178 -51
  46. data/vendor/libgit2/deps/ntlmclient/crypt_openssl.h +74 -5
  47. data/vendor/libgit2/deps/ntlmclient/ntlm.c +164 -135
  48. data/vendor/libgit2/deps/ntlmclient/ntlm.h +13 -9
  49. data/vendor/libgit2/deps/ntlmclient/ntlmclient.h +16 -3
  50. data/vendor/libgit2/deps/ntlmclient/unicode.h +10 -4
  51. data/vendor/libgit2/deps/ntlmclient/unicode_builtin.c +16 -27
  52. data/vendor/libgit2/deps/ntlmclient/unicode_builtin.h +20 -0
  53. data/vendor/libgit2/deps/ntlmclient/unicode_iconv.c +28 -52
  54. data/vendor/libgit2/deps/ntlmclient/unicode_iconv.h +22 -0
  55. data/vendor/libgit2/deps/ntlmclient/util.c +15 -1
  56. data/vendor/libgit2/deps/ntlmclient/util.h +2 -1
  57. data/vendor/libgit2/deps/pcre/LICENCE +93 -0
  58. data/vendor/libgit2/deps/pcre/pcre.h +2 -2
  59. data/vendor/libgit2/deps/pcre/pcre_compile.c +29 -17
  60. data/vendor/libgit2/deps/pcre/pcre_jit_compile.c +4 -4
  61. data/vendor/libgit2/deps/pcre/pcreposix.c +2 -3
  62. data/vendor/libgit2/deps/zlib/CMakeLists.txt +6 -5
  63. data/vendor/libgit2/deps/zlib/deflate.c +1 -0
  64. data/vendor/libgit2/include/git2/annotated_commit.h +1 -1
  65. data/vendor/libgit2/include/git2/apply.h +2 -0
  66. data/vendor/libgit2/include/git2/attr.h +89 -0
  67. data/vendor/libgit2/include/git2/blame.h +95 -42
  68. data/vendor/libgit2/include/git2/blob.h +31 -3
  69. data/vendor/libgit2/include/git2/branch.h +25 -0
  70. data/vendor/libgit2/include/git2/cert.h +42 -5
  71. data/vendor/libgit2/include/git2/checkout.h +28 -12
  72. data/vendor/libgit2/include/git2/commit.h +35 -19
  73. data/vendor/libgit2/include/git2/common.h +33 -6
  74. data/vendor/libgit2/include/git2/config.h +1 -1
  75. data/vendor/libgit2/include/git2/deprecated.h +248 -8
  76. data/vendor/libgit2/include/git2/diff.h +35 -20
  77. data/vendor/libgit2/include/git2/errors.h +8 -7
  78. data/vendor/libgit2/include/git2/filter.h +57 -17
  79. data/vendor/libgit2/include/git2/graph.h +20 -2
  80. data/vendor/libgit2/include/git2/index.h +4 -5
  81. data/vendor/libgit2/include/git2/indexer.h +2 -1
  82. data/vendor/libgit2/include/git2/odb.h +44 -20
  83. data/vendor/libgit2/include/git2/pack.h +1 -1
  84. data/vendor/libgit2/include/git2/patch.h +8 -0
  85. data/vendor/libgit2/include/git2/rebase.h +25 -1
  86. data/vendor/libgit2/include/git2/refs.h +9 -5
  87. data/vendor/libgit2/include/git2/remote.h +59 -6
  88. data/vendor/libgit2/include/git2/repository.h +95 -52
  89. data/vendor/libgit2/include/git2/revparse.h +5 -5
  90. data/vendor/libgit2/include/git2/status.h +115 -59
  91. data/vendor/libgit2/include/git2/strarray.h +6 -10
  92. data/vendor/libgit2/include/git2/submodule.h +9 -0
  93. data/vendor/libgit2/include/git2/sys/commit_graph.h +174 -0
  94. data/vendor/libgit2/include/git2/sys/filter.h +49 -28
  95. data/vendor/libgit2/include/git2/sys/midx.h +74 -0
  96. data/vendor/libgit2/include/git2/sys/odb_backend.h +7 -0
  97. data/vendor/libgit2/include/git2/sys/transport.h +1 -0
  98. data/vendor/libgit2/include/git2/tag.h +12 -0
  99. data/vendor/libgit2/include/git2/transport.h +1 -1
  100. data/vendor/libgit2/include/git2/tree.h +2 -14
  101. data/vendor/libgit2/include/git2/types.h +9 -0
  102. data/vendor/libgit2/include/git2/version.h +3 -3
  103. data/vendor/libgit2/include/git2/worktree.h +1 -0
  104. data/vendor/libgit2/src/CMakeLists.txt +77 -44
  105. data/vendor/libgit2/src/alloc.c +21 -8
  106. data/vendor/libgit2/src/allocators/failalloc.c +92 -0
  107. data/vendor/libgit2/src/allocators/failalloc.h +23 -0
  108. data/vendor/libgit2/src/allocators/stdalloc.c +41 -10
  109. data/vendor/libgit2/src/allocators/win32_leakcheck.c +118 -0
  110. data/vendor/libgit2/src/allocators/{win32_crtdbg.h → win32_leakcheck.h} +3 -3
  111. data/vendor/libgit2/src/annotated_commit.c +21 -9
  112. data/vendor/libgit2/src/apply.c +21 -8
  113. data/vendor/libgit2/src/array.h +11 -11
  114. data/vendor/libgit2/src/assert_safe.h +58 -0
  115. data/vendor/libgit2/src/attr.c +181 -74
  116. data/vendor/libgit2/src/attr_file.c +92 -42
  117. data/vendor/libgit2/src/attr_file.h +32 -11
  118. data/vendor/libgit2/src/attrcache.c +44 -40
  119. data/vendor/libgit2/src/attrcache.h +4 -5
  120. data/vendor/libgit2/src/blame.c +28 -15
  121. data/vendor/libgit2/src/blame_git.c +6 -3
  122. data/vendor/libgit2/src/blob.c +46 -24
  123. data/vendor/libgit2/src/branch.c +87 -37
  124. data/vendor/libgit2/src/buffer.c +339 -27
  125. data/vendor/libgit2/src/buffer.h +153 -2
  126. data/vendor/libgit2/src/cache.c +3 -24
  127. data/vendor/libgit2/src/cache.h +7 -7
  128. data/vendor/libgit2/src/cc-compat.h +10 -2
  129. data/vendor/libgit2/src/checkout.c +97 -98
  130. data/vendor/libgit2/src/cherrypick.c +8 -2
  131. data/vendor/libgit2/src/clone.c +104 -29
  132. data/vendor/libgit2/src/commit.c +41 -28
  133. data/vendor/libgit2/src/commit_graph.c +1209 -0
  134. data/vendor/libgit2/src/commit_graph.h +162 -0
  135. data/vendor/libgit2/src/commit_list.c +46 -0
  136. data/vendor/libgit2/src/commit_list.h +2 -0
  137. data/vendor/libgit2/src/common.h +26 -2
  138. data/vendor/libgit2/src/config.c +40 -22
  139. data/vendor/libgit2/src/config_cache.c +9 -4
  140. data/vendor/libgit2/src/config_entries.c +35 -27
  141. data/vendor/libgit2/src/config_file.c +25 -8
  142. data/vendor/libgit2/src/config_parse.c +5 -7
  143. data/vendor/libgit2/src/config_snapshot.c +2 -1
  144. data/vendor/libgit2/src/crlf.c +16 -6
  145. data/vendor/libgit2/src/date.c +4 -3
  146. data/vendor/libgit2/src/delta.c +1 -1
  147. data/vendor/libgit2/src/describe.c +11 -4
  148. data/vendor/libgit2/src/diff.c +23 -19
  149. data/vendor/libgit2/src/diff_driver.c +21 -17
  150. data/vendor/libgit2/src/diff_file.c +5 -7
  151. data/vendor/libgit2/src/diff_generate.c +56 -28
  152. data/vendor/libgit2/src/diff_parse.c +2 -3
  153. data/vendor/libgit2/src/diff_print.c +81 -65
  154. data/vendor/libgit2/src/diff_stats.c +19 -16
  155. data/vendor/libgit2/src/diff_tform.c +13 -13
  156. data/vendor/libgit2/src/diff_xdiff.c +4 -2
  157. data/vendor/libgit2/src/diff_xdiff.h +1 -1
  158. data/vendor/libgit2/src/errors.c +26 -19
  159. data/vendor/libgit2/src/features.h.in +5 -1
  160. data/vendor/libgit2/src/fetch.c +7 -2
  161. data/vendor/libgit2/src/fetchhead.c +8 -4
  162. data/vendor/libgit2/src/filebuf.c +9 -7
  163. data/vendor/libgit2/src/filter.c +209 -113
  164. data/vendor/libgit2/src/filter.h +24 -5
  165. data/vendor/libgit2/src/futils.c +8 -8
  166. data/vendor/libgit2/src/futils.h +4 -4
  167. data/vendor/libgit2/src/graph.c +64 -9
  168. data/vendor/libgit2/src/hash/sha1/collisiondetect.c +3 -3
  169. data/vendor/libgit2/src/hash/sha1/common_crypto.c +3 -3
  170. data/vendor/libgit2/src/hash/sha1/generic.h +1 -1
  171. data/vendor/libgit2/src/hash/sha1/mbedtls.c +12 -12
  172. data/vendor/libgit2/src/hash/sha1/openssl.c +3 -3
  173. data/vendor/libgit2/src/hash/sha1/sha1dc/sha1.c +0 -2
  174. data/vendor/libgit2/src/hash/sha1/win32.c +15 -11
  175. data/vendor/libgit2/src/hash.c +16 -13
  176. data/vendor/libgit2/src/hash.h +1 -1
  177. data/vendor/libgit2/src/hashsig.c +23 -10
  178. data/vendor/libgit2/src/ident.c +13 -3
  179. data/vendor/libgit2/src/idxmap.c +0 -22
  180. data/vendor/libgit2/src/ignore.c +35 -19
  181. data/vendor/libgit2/src/index.c +126 -84
  182. data/vendor/libgit2/src/index.h +1 -1
  183. data/vendor/libgit2/src/indexer.c +60 -36
  184. data/vendor/libgit2/src/integer.h +79 -2
  185. data/vendor/libgit2/src/iterator.c +40 -28
  186. data/vendor/libgit2/src/iterator.h +1 -1
  187. data/vendor/libgit2/src/khash.h +2 -11
  188. data/vendor/libgit2/src/{settings.c → libgit2.c} +125 -49
  189. data/vendor/libgit2/src/libgit2.h +15 -0
  190. data/vendor/libgit2/src/mailmap.c +23 -10
  191. data/vendor/libgit2/src/map.h +3 -3
  192. data/vendor/libgit2/src/merge.c +108 -46
  193. data/vendor/libgit2/src/merge.h +2 -1
  194. data/vendor/libgit2/src/merge_driver.c +19 -13
  195. data/vendor/libgit2/src/merge_file.c +15 -9
  196. data/vendor/libgit2/src/message.c +3 -1
  197. data/vendor/libgit2/src/midx.c +879 -0
  198. data/vendor/libgit2/src/midx.h +110 -0
  199. data/vendor/libgit2/src/mwindow.c +214 -95
  200. data/vendor/libgit2/src/mwindow.h +3 -3
  201. data/vendor/libgit2/src/net.c +133 -4
  202. data/vendor/libgit2/src/net.h +16 -2
  203. data/vendor/libgit2/src/netops.c +6 -4
  204. data/vendor/libgit2/src/netops.h +2 -2
  205. data/vendor/libgit2/src/notes.c +10 -10
  206. data/vendor/libgit2/src/object.c +24 -15
  207. data/vendor/libgit2/src/odb.c +298 -57
  208. data/vendor/libgit2/src/odb.h +16 -2
  209. data/vendor/libgit2/src/odb_loose.c +31 -21
  210. data/vendor/libgit2/src/odb_mempack.c +3 -1
  211. data/vendor/libgit2/src/odb_pack.c +391 -114
  212. data/vendor/libgit2/src/oid.c +7 -4
  213. data/vendor/libgit2/src/pack-objects.c +83 -69
  214. data/vendor/libgit2/src/pack.c +383 -150
  215. data/vendor/libgit2/src/pack.h +44 -9
  216. data/vendor/libgit2/src/patch.c +14 -7
  217. data/vendor/libgit2/src/patch_generate.c +3 -5
  218. data/vendor/libgit2/src/patch_parse.c +6 -3
  219. data/vendor/libgit2/src/path.c +102 -57
  220. data/vendor/libgit2/src/path.h +79 -6
  221. data/vendor/libgit2/src/pathspec.c +12 -11
  222. data/vendor/libgit2/src/pool.c +34 -22
  223. data/vendor/libgit2/src/pool.h +9 -1
  224. data/vendor/libgit2/src/posix.c +43 -12
  225. data/vendor/libgit2/src/posix.h +9 -0
  226. data/vendor/libgit2/src/proxy.c +2 -0
  227. data/vendor/libgit2/src/push.c +2 -0
  228. data/vendor/libgit2/src/reader.c +10 -6
  229. data/vendor/libgit2/src/rebase.c +95 -49
  230. data/vendor/libgit2/src/refdb.c +165 -13
  231. data/vendor/libgit2/src/refdb.h +69 -0
  232. data/vendor/libgit2/src/refdb_fs.c +144 -152
  233. data/vendor/libgit2/src/reflog.c +21 -20
  234. data/vendor/libgit2/src/refs.c +151 -231
  235. data/vendor/libgit2/src/refs.h +2 -20
  236. data/vendor/libgit2/src/refspec.c +80 -44
  237. data/vendor/libgit2/src/regexp.c +2 -2
  238. data/vendor/libgit2/src/remote.c +312 -121
  239. data/vendor/libgit2/src/remote.h +2 -1
  240. data/vendor/libgit2/src/repository.c +351 -189
  241. data/vendor/libgit2/src/repository.h +23 -29
  242. data/vendor/libgit2/src/reset.c +7 -6
  243. data/vendor/libgit2/src/revert.c +8 -2
  244. data/vendor/libgit2/src/revparse.c +19 -13
  245. data/vendor/libgit2/src/revwalk.c +35 -20
  246. data/vendor/libgit2/src/runtime.c +162 -0
  247. data/vendor/libgit2/src/runtime.h +62 -0
  248. data/vendor/libgit2/src/{refdb_fs.h → settings.h} +3 -11
  249. data/vendor/libgit2/src/signature.c +6 -5
  250. data/vendor/libgit2/src/sortedcache.c +2 -3
  251. data/vendor/libgit2/src/sortedcache.h +10 -8
  252. data/vendor/libgit2/src/stash.c +7 -3
  253. data/vendor/libgit2/src/status.c +9 -4
  254. data/vendor/libgit2/src/strarray.c +64 -0
  255. data/vendor/libgit2/src/streams/mbedtls.c +14 -17
  256. data/vendor/libgit2/src/streams/mbedtls.h +1 -1
  257. data/vendor/libgit2/src/streams/openssl.c +113 -207
  258. data/vendor/libgit2/src/streams/openssl.h +9 -1
  259. data/vendor/libgit2/src/streams/openssl_dynamic.c +309 -0
  260. data/vendor/libgit2/src/streams/openssl_dynamic.h +348 -0
  261. data/vendor/libgit2/src/streams/openssl_legacy.c +203 -0
  262. data/vendor/libgit2/src/streams/openssl_legacy.h +63 -0
  263. data/vendor/libgit2/src/streams/registry.c +10 -9
  264. data/vendor/libgit2/src/streams/socket.c +6 -2
  265. data/vendor/libgit2/src/streams/stransport.c +6 -3
  266. data/vendor/libgit2/src/streams/tls.c +5 -3
  267. data/vendor/libgit2/src/submodule.c +134 -66
  268. data/vendor/libgit2/src/submodule.h +9 -9
  269. data/vendor/libgit2/src/sysdir.c +8 -26
  270. data/vendor/libgit2/src/sysdir.h +0 -11
  271. data/vendor/libgit2/src/tag.c +49 -11
  272. data/vendor/libgit2/src/thread.c +140 -0
  273. data/vendor/libgit2/src/thread.h +479 -0
  274. data/vendor/libgit2/src/threadstate.c +83 -0
  275. data/vendor/libgit2/src/threadstate.h +24 -0
  276. data/vendor/libgit2/src/trace.c +2 -2
  277. data/vendor/libgit2/src/trace.h +17 -13
  278. data/vendor/libgit2/src/transaction.c +21 -9
  279. data/vendor/libgit2/src/transport.c +3 -3
  280. data/vendor/libgit2/src/transports/auth.c +1 -1
  281. data/vendor/libgit2/src/transports/auth_negotiate.c +11 -4
  282. data/vendor/libgit2/src/transports/auth_ntlm.c +10 -6
  283. data/vendor/libgit2/src/transports/credential.c +17 -7
  284. data/vendor/libgit2/src/transports/credential_helpers.c +2 -0
  285. data/vendor/libgit2/src/transports/git.c +1 -3
  286. data/vendor/libgit2/src/transports/http.c +19 -17
  287. data/vendor/libgit2/src/transports/http.h +1 -0
  288. data/vendor/libgit2/src/transports/httpclient.c +84 -42
  289. data/vendor/libgit2/src/transports/httpclient.h +1 -1
  290. data/vendor/libgit2/src/transports/local.c +5 -5
  291. data/vendor/libgit2/src/transports/smart.c +14 -9
  292. data/vendor/libgit2/src/transports/smart.h +1 -1
  293. data/vendor/libgit2/src/transports/smart_protocol.c +11 -5
  294. data/vendor/libgit2/src/transports/ssh.c +51 -17
  295. data/vendor/libgit2/src/transports/winhttp.c +156 -88
  296. data/vendor/libgit2/src/tree.c +100 -77
  297. data/vendor/libgit2/src/tree.h +1 -0
  298. data/vendor/libgit2/src/tsort.c +0 -2
  299. data/vendor/libgit2/src/unix/map.c +3 -1
  300. data/vendor/libgit2/src/unix/posix.h +16 -1
  301. data/vendor/libgit2/src/unix/pthread.h +2 -1
  302. data/vendor/libgit2/src/utf8.c +150 -0
  303. data/vendor/libgit2/src/utf8.h +52 -0
  304. data/vendor/libgit2/src/util.c +74 -183
  305. data/vendor/libgit2/src/util.h +33 -39
  306. data/vendor/libgit2/src/vector.c +23 -19
  307. data/vendor/libgit2/src/vector.h +4 -2
  308. data/vendor/libgit2/src/win32/findfile.c +4 -2
  309. data/vendor/libgit2/src/win32/git2.rc +18 -3
  310. data/vendor/libgit2/src/win32/map.c +1 -1
  311. data/vendor/libgit2/src/win32/msvc-compat.h +9 -1
  312. data/vendor/libgit2/src/win32/path_w32.c +23 -25
  313. data/vendor/libgit2/src/win32/path_w32.h +0 -1
  314. data/vendor/libgit2/src/win32/posix_w32.c +77 -1
  315. data/vendor/libgit2/src/win32/precompiled.h +0 -1
  316. data/vendor/libgit2/src/win32/reparse.h +4 -4
  317. data/vendor/libgit2/src/win32/thread.c +24 -15
  318. data/vendor/libgit2/src/win32/thread.h +1 -1
  319. data/vendor/libgit2/src/win32/w32_buffer.c +3 -3
  320. data/vendor/libgit2/src/win32/w32_common.h +18 -9
  321. data/vendor/libgit2/src/win32/{w32_crtdbg_stacktrace.c → w32_leakcheck.c} +269 -33
  322. data/vendor/libgit2/src/win32/w32_leakcheck.h +222 -0
  323. data/vendor/libgit2/src/win32/w32_util.h +6 -6
  324. data/vendor/libgit2/src/worktree.c +37 -15
  325. data/vendor/libgit2/src/zstream.c +1 -1
  326. metadata +56 -38
  327. data/vendor/libgit2/cmake/Modules/CheckPrototypeDefinition.c.in +0 -29
  328. data/vendor/libgit2/cmake/Modules/CheckPrototypeDefinition.cmake +0 -96
  329. data/vendor/libgit2/src/allocators/win32_crtdbg.c +0 -118
  330. data/vendor/libgit2/src/buf_text.c +0 -316
  331. data/vendor/libgit2/src/buf_text.h +0 -122
  332. data/vendor/libgit2/src/global.c +0 -361
  333. data/vendor/libgit2/src/global.h +0 -41
  334. data/vendor/libgit2/src/thread-utils.c +0 -58
  335. data/vendor/libgit2/src/thread-utils.h +0 -246
  336. data/vendor/libgit2/src/win32/w32_crtdbg_stacktrace.h +0 -127
  337. data/vendor/libgit2/src/win32/w32_stack.c +0 -188
  338. data/vendor/libgit2/src/win32/w32_stack.h +0 -140
@@ -12,16 +12,21 @@
12
12
  #include "git2/odb.h"
13
13
  #include "git2/oid.h"
14
14
  #include "git2/types.h"
15
+ #include "git2/sys/commit_graph.h"
15
16
 
16
- #include "vector.h"
17
17
  #include "cache.h"
18
- #include "posix.h"
18
+ #include "commit_graph.h"
19
19
  #include "filter.h"
20
+ #include "posix.h"
21
+ #include "vector.h"
20
22
 
21
23
  #define GIT_OBJECTS_DIR "objects/"
22
24
  #define GIT_OBJECT_DIR_MODE 0777
23
25
  #define GIT_OBJECT_FILE_MODE 0444
24
26
 
27
+ #define GIT_ODB_DEFAULT_LOOSE_PRIORITY 1
28
+ #define GIT_ODB_DEFAULT_PACKED_PRIORITY 2
29
+
25
30
  extern bool git_odb__strict_hash_verification;
26
31
 
27
32
  /* DO NOT EXPORT */
@@ -40,8 +45,10 @@ struct git_odb_object {
40
45
  /* EXPORT */
41
46
  struct git_odb {
42
47
  git_refcount rc;
48
+ git_mutex lock; /* protects backends */
43
49
  git_vector backends;
44
50
  git_cache own_cache;
51
+ git_commit_graph *cgraph;
45
52
  unsigned int do_fsync :1;
46
53
  };
47
54
 
@@ -126,6 +133,13 @@ int git_odb__read_header_or_object(
126
133
  git_odb_object **out, size_t *len_p, git_object_t *type_p,
127
134
  git_odb *db, const git_oid *id);
128
135
 
136
+ /*
137
+ * Attempt to get the ODB's commit-graph file. This object is still owned by
138
+ * the ODB. If the repository does not contain a commit-graph, it will return
139
+ * GIT_ENOTFOUND.
140
+ */
141
+ int git_odb__get_commit_graph_file(git_commit_graph_file **out, git_odb *odb);
142
+
129
143
  /* freshen an entry in the object database */
130
144
  int git_odb__freshen(git_odb *db, const git_oid *id);
131
145
 
@@ -304,12 +304,12 @@ static int read_loose_standard(git_rawobj *out, git_buf *obj)
304
304
  * (including the initial sequence in the head buffer).
305
305
  */
306
306
  if (GIT_ADD_SIZET_OVERFLOW(&alloc_size, hdr.size, 1) ||
307
- (body = git__malloc(alloc_size)) == NULL) {
307
+ (body = git__calloc(1, alloc_size)) == NULL) {
308
308
  error = -1;
309
309
  goto done;
310
310
  }
311
311
 
312
- assert(decompressed >= head_len);
312
+ GIT_ASSERT(decompressed >= head_len);
313
313
  body_len = decompressed - head_len;
314
314
 
315
315
  if (body_len)
@@ -344,7 +344,8 @@ static int read_loose(git_rawobj *out, git_buf *loc)
344
344
  int error;
345
345
  git_buf obj = GIT_BUF_INIT;
346
346
 
347
- assert(out && loc);
347
+ GIT_ASSERT_ARG(out);
348
+ GIT_ASSERT_ARG(loc);
348
349
 
349
350
  if (git_buf_oom(loc))
350
351
  return -1;
@@ -386,8 +387,8 @@ static int read_header_loose_standard(
386
387
  git_rawobj *out, const unsigned char *data, size_t len)
387
388
  {
388
389
  git_zstream zs = GIT_ZSTREAM_INIT;
389
- obj_hdr hdr;
390
- unsigned char inflated[MAX_HEADER_LEN];
390
+ obj_hdr hdr = {0};
391
+ unsigned char inflated[MAX_HEADER_LEN] = {0};
391
392
  size_t header_len, inflated_len = sizeof(inflated);
392
393
  int error;
393
394
 
@@ -411,7 +412,8 @@ static int read_header_loose(git_rawobj *out, git_buf *loc)
411
412
  ssize_t obj_len;
412
413
  int fd, error;
413
414
 
414
- assert(out && loc);
415
+ GIT_ASSERT_ARG(out);
416
+ GIT_ASSERT_ARG(loc);
415
417
 
416
418
  if (git_buf_oom(loc))
417
419
  return -1;
@@ -585,7 +587,8 @@ static int loose_backend__read_header(size_t *len_p, git_object_t *type_p, git_o
585
587
  git_rawobj raw;
586
588
  int error;
587
589
 
588
- assert(backend && oid);
590
+ GIT_ASSERT_ARG(backend);
591
+ GIT_ASSERT_ARG(oid);
589
592
 
590
593
  raw.len = 0;
591
594
  raw.type = GIT_OBJECT_INVALID;
@@ -609,7 +612,8 @@ static int loose_backend__read(void **buffer_p, size_t *len_p, git_object_t *typ
609
612
  git_rawobj raw;
610
613
  int error = 0;
611
614
 
612
- assert(backend && oid);
615
+ GIT_ASSERT_ARG(backend);
616
+ GIT_ASSERT_ARG(oid);
613
617
 
614
618
  if (locate_object(&object_path, (loose_backend *)backend, oid) < 0) {
615
619
  error = git_odb__error_notfound("no matching loose object",
@@ -636,7 +640,7 @@ static int loose_backend__read_prefix(
636
640
  {
637
641
  int error = 0;
638
642
 
639
- assert(len >= GIT_OID_MINPREFIXLEN && len <= GIT_OID_HEXSZ);
643
+ GIT_ASSERT_ARG(len >= GIT_OID_MINPREFIXLEN && len <= GIT_OID_HEXSZ);
640
644
 
641
645
  if (len == GIT_OID_HEXSZ) {
642
646
  /* We can fall back to regular read method */
@@ -647,7 +651,7 @@ static int loose_backend__read_prefix(
647
651
  git_buf object_path = GIT_BUF_INIT;
648
652
  git_rawobj raw;
649
653
 
650
- assert(backend && short_oid);
654
+ GIT_ASSERT_ARG(backend && short_oid);
651
655
 
652
656
  if ((error = locate_object_short_oid(&object_path, out_oid,
653
657
  (loose_backend *)backend, short_oid, len)) == 0 &&
@@ -669,7 +673,8 @@ static int loose_backend__exists(git_odb_backend *backend, const git_oid *oid)
669
673
  git_buf object_path = GIT_BUF_INIT;
670
674
  int error;
671
675
 
672
- assert(backend && oid);
676
+ GIT_ASSERT_ARG(backend);
677
+ GIT_ASSERT_ARG(oid);
673
678
 
674
679
  error = locate_object(&object_path, (loose_backend *)backend, oid);
675
680
 
@@ -684,7 +689,10 @@ static int loose_backend__exists_prefix(
684
689
  git_buf object_path = GIT_BUF_INIT;
685
690
  int error;
686
691
 
687
- assert(backend && out && short_id && len >= GIT_OID_MINPREFIXLEN);
692
+ GIT_ASSERT_ARG(backend);
693
+ GIT_ASSERT_ARG(out);
694
+ GIT_ASSERT_ARG(short_id);
695
+ GIT_ASSERT_ARG(len >= GIT_OID_MINPREFIXLEN);
688
696
 
689
697
  error = locate_object_short_oid(
690
698
  &object_path, out, (loose_backend *)backend, short_id, len);
@@ -759,7 +767,8 @@ static int loose_backend__foreach(git_odb_backend *_backend, git_odb_foreach_cb
759
767
  struct foreach_state state;
760
768
  loose_backend *backend = (loose_backend *) _backend;
761
769
 
762
- assert(backend && cb);
770
+ GIT_ASSERT_ARG(backend);
771
+ GIT_ASSERT_ARG(cb);
763
772
 
764
773
  objects_dir = backend->objects_dir;
765
774
 
@@ -833,7 +842,7 @@ static int loose_backend__writestream(git_odb_stream **stream_out, git_odb_backe
833
842
  size_t hdrlen;
834
843
  int error;
835
844
 
836
- assert(_backend);
845
+ GIT_ASSERT_ARG(_backend);
837
846
 
838
847
  backend = (loose_backend *)_backend;
839
848
  *stream_out = NULL;
@@ -991,7 +1000,11 @@ static int loose_backend__readstream(
991
1000
  obj_hdr hdr;
992
1001
  int error = 0;
993
1002
 
994
- assert(stream_out && len_out && type_out && _backend && oid);
1003
+ GIT_ASSERT_ARG(stream_out);
1004
+ GIT_ASSERT_ARG(len_out);
1005
+ GIT_ASSERT_ARG(type_out);
1006
+ GIT_ASSERT_ARG(_backend);
1007
+ GIT_ASSERT_ARG(oid);
995
1008
 
996
1009
  backend = (loose_backend *)_backend;
997
1010
  *stream_out = NULL;
@@ -1108,11 +1121,7 @@ static int loose_backend__freshen(
1108
1121
 
1109
1122
  static void loose_backend__free(git_odb_backend *_backend)
1110
1123
  {
1111
- loose_backend *backend;
1112
- assert(_backend);
1113
- backend = (loose_backend *)_backend;
1114
-
1115
- git__free(backend);
1124
+ git__free(_backend);
1116
1125
  }
1117
1126
 
1118
1127
  int git_odb_backend_loose(
@@ -1126,7 +1135,8 @@ int git_odb_backend_loose(
1126
1135
  loose_backend *backend;
1127
1136
  size_t objects_dirlen, alloclen;
1128
1137
 
1129
- assert(backend_out && objects_dir);
1138
+ GIT_ASSERT_ARG(backend_out);
1139
+ GIT_ASSERT_ARG(objects_dir);
1130
1140
 
1131
1141
  objects_dirlen = strlen(objects_dir);
1132
1142
 
@@ -110,6 +110,8 @@ int git_mempack_dump(git_buf *pack, git_repository *repo, git_odb_backend *_back
110
110
  if (git_packbuilder_new(&packbuilder, repo) < 0)
111
111
  return -1;
112
112
 
113
+ git_packbuilder_set_threads(packbuilder, 0);
114
+
113
115
  for (i = 0; i < db->commits.size; ++i) {
114
116
  struct memobject *commit = db->commits.ptr[i];
115
117
 
@@ -154,7 +156,7 @@ int git_mempack_new(git_odb_backend **out)
154
156
  {
155
157
  struct memory_packer_db *db;
156
158
 
157
- assert(out);
159
+ GIT_ASSERT_ARG(out);
158
160
 
159
161
  db = git__calloc(1, sizeof(struct memory_packer_db));
160
162
  GIT_ERROR_CHECK_ALLOC(db);
@@ -11,11 +11,12 @@
11
11
  #include "git2/repository.h"
12
12
  #include "git2/indexer.h"
13
13
  #include "git2/sys/odb_backend.h"
14
+ #include "delta.h"
14
15
  #include "futils.h"
15
16
  #include "hash.h"
16
- #include "odb.h"
17
- #include "delta.h"
17
+ #include "midx.h"
18
18
  #include "mwindow.h"
19
+ #include "odb.h"
19
20
  #include "pack.h"
20
21
 
21
22
  #include "git2/odb_backend.h"
@@ -25,6 +26,8 @@
25
26
 
26
27
  struct pack_backend {
27
28
  git_odb_backend parent;
29
+ git_midx_file *midx;
30
+ git_vector midx_packs;
28
31
  git_vector packs;
29
32
  struct git_pack_file *last_found;
30
33
  char *pack_folder;
@@ -47,36 +50,43 @@ struct pack_writepack {
47
50
  * Initialization of the Pack Backend
48
51
  * --------------------------------------------------
49
52
  *
50
- * # git_odb_backend_pack
51
- * | Creates the pack backend structure, initializes the
52
- * | callback pointers to our default read() and exist() methods,
53
- * | and tries to preload all the known packfiles in the ODB.
53
+ * # git_odb_backend_pack
54
+ * | Creates the pack backend structure, initializes the
55
+ * | callback pointers to our default read() and exist() methods,
56
+ * | and tries to find the `pack` folder, if it exists. ODBs without a `pack`
57
+ * | folder are ignored altogether. If there is a `pack` folder, it tries to
58
+ * | preload all the known packfiles in the ODB.
54
59
  * |
55
- * |-# packfile_load_all
56
- * | Tries to find the `pack` folder, if it exists. ODBs without
57
- * | a pack folder are ignored altogether. If there's a `pack` folder
58
- * | we run a `dirent` callback through every file in the pack folder
59
- * | to find our packfiles. The packfiles are then sorted according
60
- * | to a sorting callback.
61
- * |
62
- * |-# packfile_load__cb
63
- * | | This callback is called from `dirent` with every single file
64
- * | | inside the pack folder. We find the packs by actually locating
65
- * | | their index (ends in ".idx"). From that index, we verify that
66
- * | | the corresponding packfile exists and is valid, and if so, we
67
- * | | add it to the pack list.
68
- * | |
69
- * | |-# packfile_check
70
- * | Make sure that there's a packfile to back this index, and store
71
- * | some very basic information regarding the packfile itself,
72
- * | such as the full path, the size, and the modification time.
73
- * | We don't actually open the packfile to check for internal consistency.
74
- * |
75
- * |-# packfile_sort__cb
76
- * Sort all the preloaded packs according to some specific criteria:
77
- * we prioritize the "newer" packs because it's more likely they
78
- * contain the objects we are looking for, and we prioritize local
79
- * packs over remote ones.
60
+ * |-# pack_backend__refresh
61
+ * | The `multi-pack-index` is loaded if it exists and is valid.
62
+ * | Then we run a `dirent` callback through every file in the pack folder,
63
+ * | even those present in `multi-pack-index`. The unindexed packfiles are
64
+ * | then sorted according to a sorting callback.
65
+ * |
66
+ * |-# refresh_multi_pack_index
67
+ * | Detect the presence of the `multi-pack-index` file. If it needs to be
68
+ * | refreshed, frees the old copy and tries to load the new one, together
69
+ * | with all the packfiles it indexes. If the process fails, fall back to
70
+ * | the old behavior, as if the `multi-pack-index` file was not there.
71
+ * |
72
+ * |-# packfile_load__cb
73
+ * | | This callback is called from `dirent` with every single file
74
+ * | | inside the pack folder. We find the packs by actually locating
75
+ * | | their index (ends in ".idx"). From that index, we verify that
76
+ * | | the corresponding packfile exists and is valid, and if so, we
77
+ * | | add it to the pack list.
78
+ * | |
79
+ * | # git_mwindow_get_pack
80
+ * | Make sure that there's a packfile to back this index, and store
81
+ * | some very basic information regarding the packfile itself,
82
+ * | such as the full path, the size, and the modification time.
83
+ * | We don't actually open the packfile to check for internal consistency.
84
+ * |
85
+ * |-# packfile_sort__cb
86
+ * Sort all the preloaded packs according to some specific criteria:
87
+ * we prioritize the "newer" packs because it's more likely they
88
+ * contain the objects we are looking for, and we prioritize local
89
+ * packs over remote ones.
80
90
  *
81
91
  *
82
92
  *
@@ -84,48 +94,66 @@ struct pack_writepack {
84
94
  * A standard packed `exist` query for an OID
85
95
  * --------------------------------------------------
86
96
  *
87
- * # pack_backend__exists
88
- * | Check if the given SHA1 oid exists in any of the packs
89
- * | that have been loaded for our ODB.
97
+ * # pack_backend__exists / pack_backend__exists_prefix
98
+ * | Check if the given SHA1 oid (or a SHA1 oid prefix) exists in any of the
99
+ * | packs that have been loaded for our ODB.
90
100
  * |
91
- * |-# pack_entry_find
92
- * | Iterate through all the packs that have been preloaded
93
- * | (starting by the pack where the latest object was found)
94
- * | to try to find the OID in one of them.
95
- * |
96
- * |-# pack_entry_find1
97
- * | Check the index of an individual pack to see if the SHA1
98
- * | OID can be found. If we can find the offset to that SHA1
99
- * | inside of the index, that means the object is contained
100
- * | inside of the packfile and we can stop searching.
101
- * | Before returning, we verify that the packfile behing the
102
- * | index we are searching still exists on disk.
103
- * |
104
- * |-# pack_entry_find_offset
105
- * | | Mmap the actual index file to disk if it hasn't been opened
106
- * | | yet, and run a binary search through it to find the OID.
107
- * | | See <http://book.git-scm.com/7_the_packfile.html> for specifics
108
- * | | on the Packfile Index format and how do we find entries in it.
109
- * | |
110
- * | |-# pack_index_open
111
- * | | Guess the name of the index based on the full path to the
112
- * | | packfile, open it and verify its contents. Only if the index
113
- * | | has not been opened already.
114
- * | |
115
- * | |-# pack_index_check
116
- * | Mmap the index file and do a quick run through the header
117
- * | to guess the index version (right now we support v1 and v2),
118
- * | and to verify that the size of the index makes sense.
119
- * |
120
- * |-# packfile_open
121
- * See `packfile_open` in Chapter 3
101
+ * |-# pack_entry_find / pack_entry_find_prefix
102
+ * | If there is a multi-pack-index present, search the SHA1 oid in that
103
+ * | index first. If it is not found there, iterate through all the unindexed
104
+ * | packs that have been preloaded (starting by the pack where the latest
105
+ * | object was found) to try to find the OID in one of them.
106
+ * |
107
+ * |-# git_midx_entry_find
108
+ * | Search for the SHA1 oid in the multi-pack-index. See
109
+ * | <https://github.com/git/git/blob/master/Documentation/technical/pack-format.txt>
110
+ * | for specifics on the multi-pack-index format and how do we find
111
+ * | entries in it.
112
+ * |
113
+ * |-# git_pack_entry_find
114
+ * | Check the index of an individual unindexed pack to see if the SHA1
115
+ * | OID can be found. If we can find the offset to that SHA1 inside of the
116
+ * | index, that means the object is contained inside of the packfile and
117
+ * | we can stop searching. Before returning, we verify that the
118
+ * | packfile behing the index we are searching still exists on disk.
119
+ * |
120
+ * |-# pack_entry_find_offset
121
+ * | Mmap the actual index file to disk if it hasn't been opened
122
+ * | yet, and run a binary search through it to find the OID.
123
+ * | See <https://github.com/git/git/blob/master/Documentation/technical/pack-format.txt>
124
+ * | for specifics on the Packfile Index format and how do we find
125
+ * | entries in it.
126
+ * |
127
+ * |-# pack_index_open
128
+ * | Guess the name of the index based on the full path to the
129
+ * | packfile, open it and verify its contents. Only if the index
130
+ * | has not been opened already.
131
+ * |
132
+ * |-# pack_index_check
133
+ * Mmap the index file and do a quick run through the header
134
+ * to guess the index version (right now we support v1 and v2),
135
+ * and to verify that the size of the index makes sense.
122
136
  *
123
137
  *
124
138
  *
125
139
  * Chapter 3: The neverending story...
126
140
  * A standard packed `lookup` query for an OID
127
141
  * --------------------------------------------------
128
- * TODO
142
+ *
143
+ * # pack_backend__read / pack_backend__read_prefix
144
+ * | Check if the given SHA1 oid (or a SHA1 oid prefix) exists in any of the
145
+ * | packs that have been loaded for our ODB. If it does, open the packfile and
146
+ * | read from it.
147
+ * |
148
+ * |-# git_packfile_unpack
149
+ * Armed with a packfile and the offset within it, we can finally unpack
150
+ * the object pointed at by the SHA1 oid. This involves mmapping part of
151
+ * the `.pack` file, and uncompressing the object within it (if it is
152
+ * stored in the undelfitied representation), or finding a base object and
153
+ * applying some deltas to its uncompressed representation (if it is stored
154
+ * in the deltified representation). See
155
+ * <https://github.com/git/git/blob/master/Documentation/technical/pack-format.txt>
156
+ * for specifics on the Packfile format and how do we read from it.
129
157
  *
130
158
  */
131
159
 
@@ -140,6 +168,8 @@ static int packfile_sort__cb(const void *a_, const void *b_);
140
168
 
141
169
  static int packfile_load__cb(void *_data, git_buf *path);
142
170
 
171
+ static int packfile_byname_search_cmp(const void *path, const void *pack_entry);
172
+
143
173
  static int pack_entry_find(struct git_pack_entry *e,
144
174
  struct pack_backend *backend, const git_oid *oid);
145
175
 
@@ -163,6 +193,14 @@ static int pack_entry_find_prefix(
163
193
  *
164
194
  ***********************************************************/
165
195
 
196
+ static int packfile_byname_search_cmp(const void *path_, const void *p_)
197
+ {
198
+ const git_buf *path = (const git_buf *)path_;
199
+ const struct git_pack_file *p = (const struct git_pack_file *)p_;
200
+
201
+ return strncmp(p->pack_name, git_buf_cstr(path), git_buf_len(path));
202
+ }
203
+
166
204
  static int packfile_sort__cb(const void *a_, const void *b_)
167
205
  {
168
206
  const struct git_pack_file *a = a_;
@@ -198,20 +236,20 @@ static int packfile_load__cb(void *data, git_buf *path)
198
236
  struct pack_backend *backend = data;
199
237
  struct git_pack_file *pack;
200
238
  const char *path_str = git_buf_cstr(path);
201
- size_t i, cmp_len = git_buf_len(path);
239
+ git_buf index_prefix = GIT_BUF_INIT;
240
+ size_t cmp_len = git_buf_len(path);
202
241
  int error;
203
242
 
204
243
  if (cmp_len <= strlen(".idx") || git__suffixcmp(path_str, ".idx") != 0)
205
244
  return 0; /* not an index */
206
245
 
207
246
  cmp_len -= strlen(".idx");
247
+ git_buf_attach_notowned(&index_prefix, path_str, cmp_len);
208
248
 
209
- for (i = 0; i < backend->packs.length; ++i) {
210
- struct git_pack_file *p = git_vector_get(&backend->packs, i);
211
-
212
- if (strncmp(p->pack_name, path_str, cmp_len) == 0)
213
- return 0;
214
- }
249
+ if (git_vector_search2(NULL, &backend->midx_packs, packfile_byname_search_cmp, &index_prefix) == 0)
250
+ return 0;
251
+ if (git_vector_search2(NULL, &backend->packs, packfile_byname_search_cmp, &index_prefix) == 0)
252
+ return 0;
215
253
 
216
254
  error = git_mwindow_get_pack(&pack, path->ptr);
217
255
 
@@ -228,22 +266,26 @@ static int packfile_load__cb(void *data, git_buf *path)
228
266
 
229
267
  }
230
268
 
231
- static int pack_entry_find_inner(
232
- struct git_pack_entry *e,
233
- struct pack_backend *backend,
234
- const git_oid *oid,
235
- struct git_pack_file *last_found)
269
+ static int pack_entry_find(struct git_pack_entry *e, struct pack_backend *backend, const git_oid *oid)
236
270
  {
271
+ struct git_pack_file *last_found = backend->last_found, *p;
272
+ git_midx_entry midx_entry;
237
273
  size_t i;
238
274
 
275
+ if (backend->midx &&
276
+ git_midx_entry_find(&midx_entry, backend->midx, oid, GIT_OID_HEXSZ) == 0 &&
277
+ midx_entry.pack_index < git_vector_length(&backend->midx_packs)) {
278
+ e->offset = midx_entry.offset;
279
+ git_oid_cpy(&e->sha1, &midx_entry.sha1);
280
+ e->p = git_vector_get(&backend->midx_packs, midx_entry.pack_index);
281
+ return 0;
282
+ }
283
+
239
284
  if (last_found &&
240
285
  git_pack_entry_find(e, last_found, oid, GIT_OID_HEXSZ) == 0)
241
286
  return 0;
242
287
 
243
- for (i = 0; i < backend->packs.length; ++i) {
244
- struct git_pack_file *p;
245
-
246
- p = git_vector_get(&backend->packs, i);
288
+ git_vector_foreach(&backend->packs, i, p) {
247
289
  if (p == last_found)
248
290
  continue;
249
291
 
@@ -253,20 +295,6 @@ static int pack_entry_find_inner(
253
295
  }
254
296
  }
255
297
 
256
- return -1;
257
- }
258
-
259
- static int pack_entry_find(struct git_pack_entry *e, struct pack_backend *backend, const git_oid *oid)
260
- {
261
- struct git_pack_file *last_found = backend->last_found;
262
-
263
- if (backend->last_found &&
264
- git_pack_entry_find(e, backend->last_found, oid, GIT_OID_HEXSZ) == 0)
265
- return 0;
266
-
267
- if (!pack_entry_find_inner(e, backend, oid, last_found))
268
- return 0;
269
-
270
298
  return git_odb__error_notfound(
271
299
  "failed to find pack entry", oid, GIT_OID_HEXSZ);
272
300
  }
@@ -281,22 +309,35 @@ static int pack_entry_find_prefix(
281
309
  size_t i;
282
310
  git_oid found_full_oid = {{0}};
283
311
  bool found = false;
284
- struct git_pack_file *last_found = backend->last_found;
312
+ struct git_pack_file *last_found = backend->last_found, *p;
313
+ git_midx_entry midx_entry;
314
+
315
+ if (backend->midx) {
316
+ error = git_midx_entry_find(&midx_entry, backend->midx, short_oid, len);
317
+ if (error == GIT_EAMBIGUOUS)
318
+ return error;
319
+ if (!error && midx_entry.pack_index < git_vector_length(&backend->midx_packs)) {
320
+ e->offset = midx_entry.offset;
321
+ git_oid_cpy(&e->sha1, &midx_entry.sha1);
322
+ e->p = git_vector_get(&backend->midx_packs, midx_entry.pack_index);
323
+ git_oid_cpy(&found_full_oid, &e->sha1);
324
+ found = true;
325
+ }
326
+ }
285
327
 
286
328
  if (last_found) {
287
329
  error = git_pack_entry_find(e, last_found, short_oid, len);
288
330
  if (error == GIT_EAMBIGUOUS)
289
331
  return error;
290
332
  if (!error) {
333
+ if (found && git_oid_cmp(&e->sha1, &found_full_oid))
334
+ return git_odb__error_ambiguous("found multiple pack entries");
291
335
  git_oid_cpy(&found_full_oid, &e->sha1);
292
336
  found = true;
293
337
  }
294
338
  }
295
339
 
296
- for (i = 0; i < backend->packs.length; ++i) {
297
- struct git_pack_file *p;
298
-
299
- p = git_vector_get(&backend->packs, i);
340
+ git_vector_foreach(&backend->packs, i, p) {
300
341
  if (p == last_found)
301
342
  continue;
302
343
 
@@ -319,6 +360,139 @@ static int pack_entry_find_prefix(
319
360
  return 0;
320
361
  }
321
362
 
363
+ /***********************************************************
364
+ *
365
+ * MULTI-PACK-INDEX SUPPORT
366
+ *
367
+ * Functions needed to support the multi-pack-index.
368
+ *
369
+ ***********************************************************/
370
+
371
+ /*
372
+ * Remove the multi-pack-index, and move all midx_packs to packs.
373
+ */
374
+ static int remove_multi_pack_index(struct pack_backend *backend)
375
+ {
376
+ size_t i, j = git_vector_length(&backend->packs);
377
+ struct pack_backend *p;
378
+ int error = git_vector_size_hint(
379
+ &backend->packs,
380
+ j + git_vector_length(&backend->midx_packs));
381
+ if (error < 0)
382
+ return error;
383
+
384
+ git_vector_foreach(&backend->midx_packs, i, p)
385
+ git_vector_set(NULL, &backend->packs, j++, p);
386
+ git_vector_clear(&backend->midx_packs);
387
+
388
+ git_midx_free(backend->midx);
389
+ backend->midx = NULL;
390
+
391
+ return 0;
392
+ }
393
+
394
+ /*
395
+ * Loads a single .pack file referred to by the multi-pack-index. These must
396
+ * match the order in which they are declared in the multi-pack-index file,
397
+ * since these files are referred to by their index.
398
+ */
399
+ static int process_multi_pack_index_pack(
400
+ struct pack_backend *backend,
401
+ size_t i,
402
+ const char *packfile_name)
403
+ {
404
+ int error;
405
+ struct git_pack_file *pack;
406
+ size_t found_position;
407
+ git_buf pack_path = GIT_BUF_INIT, index_prefix = GIT_BUF_INIT;
408
+
409
+ error = git_buf_joinpath(&pack_path, backend->pack_folder, packfile_name);
410
+ if (error < 0)
411
+ return error;
412
+
413
+ /* This is ensured by midx_parse_packfile_name() */
414
+ if (git_buf_len(&pack_path) <= strlen(".idx") || git__suffixcmp(git_buf_cstr(&pack_path), ".idx") != 0)
415
+ return git_odb__error_notfound("midx file contained a non-index", NULL, 0);
416
+
417
+ git_buf_attach_notowned(&index_prefix, git_buf_cstr(&pack_path), git_buf_len(&pack_path) - strlen(".idx"));
418
+
419
+ if (git_vector_search2(&found_position, &backend->packs, packfile_byname_search_cmp, &index_prefix) == 0) {
420
+ /* Pack was found in the packs list. Moving it to the midx_packs list. */
421
+ git_buf_dispose(&pack_path);
422
+ git_vector_set(NULL, &backend->midx_packs, i, git_vector_get(&backend->packs, found_position));
423
+ git_vector_remove(&backend->packs, found_position);
424
+ return 0;
425
+ }
426
+
427
+ /* Pack was not found. Allocate a new one. */
428
+ error = git_mwindow_get_pack(&pack, git_buf_cstr(&pack_path));
429
+ git_buf_dispose(&pack_path);
430
+ if (error < 0)
431
+ return error;
432
+
433
+ git_vector_set(NULL, &backend->midx_packs, i, pack);
434
+ return 0;
435
+ }
436
+
437
+ /*
438
+ * Reads the multi-pack-index. If this fails for whatever reason, the
439
+ * multi-pack-index object is freed, and all the packfiles that are related to
440
+ * it are moved to the unindexed packfiles vector.
441
+ */
442
+ static int refresh_multi_pack_index(struct pack_backend *backend)
443
+ {
444
+ int error;
445
+ git_buf midx_path = GIT_BUF_INIT;
446
+ const char *packfile_name;
447
+ size_t i;
448
+
449
+ error = git_buf_joinpath(&midx_path, backend->pack_folder, "multi-pack-index");
450
+ if (error < 0)
451
+ return error;
452
+
453
+ /*
454
+ * Check whether the multi-pack-index has changed. If it has, close any
455
+ * old multi-pack-index and move all the packfiles to the unindexed
456
+ * packs. This is done to prevent losing any open packfiles in case
457
+ * refreshing the new multi-pack-index fails, or the file is deleted.
458
+ */
459
+ if (backend->midx) {
460
+ if (!git_midx_needs_refresh(backend->midx, git_buf_cstr(&midx_path))) {
461
+ git_buf_dispose(&midx_path);
462
+ return 0;
463
+ }
464
+ error = remove_multi_pack_index(backend);
465
+ if (error < 0) {
466
+ git_buf_dispose(&midx_path);
467
+ return error;
468
+ }
469
+ }
470
+
471
+ error = git_midx_open(&backend->midx, git_buf_cstr(&midx_path));
472
+ git_buf_dispose(&midx_path);
473
+ if (error < 0)
474
+ return error;
475
+
476
+ git_vector_resize_to(&backend->midx_packs, git_vector_length(&backend->midx->packfile_names));
477
+
478
+ git_vector_foreach(&backend->midx->packfile_names, i, packfile_name) {
479
+ error = process_multi_pack_index_pack(backend, i, packfile_name);
480
+ if (error < 0) {
481
+ /*
482
+ * Something failed during reading multi-pack-index.
483
+ * Restore the state of backend as if the
484
+ * multi-pack-index was never there, and move all
485
+ * packfiles that have been processed so far to the
486
+ * unindexed packs.
487
+ */
488
+ git_vector_resize_to(&backend->midx_packs, i);
489
+ remove_multi_pack_index(backend);
490
+ return error;
491
+ }
492
+ }
493
+
494
+ return 0;
495
+ }
322
496
 
323
497
  /***********************************************************
324
498
  *
@@ -340,9 +514,16 @@ static int pack_backend__refresh(git_odb_backend *backend_)
340
514
  if (p_stat(backend->pack_folder, &st) < 0 || !S_ISDIR(st.st_mode))
341
515
  return git_odb__error_notfound("failed to refresh packfiles", NULL, 0);
342
516
 
343
- git_buf_sets(&path, backend->pack_folder);
517
+ if (refresh_multi_pack_index(backend) < 0) {
518
+ /*
519
+ * It is okay if this fails. We will just not use the
520
+ * multi-pack-index in this case.
521
+ */
522
+ git_error_clear();
523
+ }
344
524
 
345
525
  /* reload all packs */
526
+ git_buf_sets(&path, backend->pack_folder);
346
527
  error = git_path_direach(&path, 0, packfile_load__cb, backend);
347
528
 
348
529
  git_buf_dispose(&path);
@@ -358,7 +539,10 @@ static int pack_backend__read_header(
358
539
  struct git_pack_entry e;
359
540
  int error;
360
541
 
361
- assert(len_p && type_p && backend && oid);
542
+ GIT_ASSERT_ARG(len_p);
543
+ GIT_ASSERT_ARG(type_p);
544
+ GIT_ASSERT_ARG(backend);
545
+ GIT_ASSERT_ARG(oid);
362
546
 
363
547
  if ((error = pack_entry_find(&e, (struct pack_backend *)backend, oid)) < 0)
364
548
  return error;
@@ -469,13 +653,17 @@ static int pack_backend__foreach(git_odb_backend *_backend, git_odb_foreach_cb c
469
653
  struct pack_backend *backend;
470
654
  unsigned int i;
471
655
 
472
- assert(_backend && cb);
656
+ GIT_ASSERT_ARG(_backend);
657
+ GIT_ASSERT_ARG(cb);
658
+
473
659
  backend = (struct pack_backend *)_backend;
474
660
 
475
661
  /* Make sure we know about the packfiles */
476
- if ((error = pack_backend__refresh(_backend)) < 0)
662
+ if ((error = pack_backend__refresh(_backend)) != 0)
477
663
  return error;
478
664
 
665
+ if (backend->midx && (error = git_midx_foreach_entry(backend->midx, cb, data)) != 0)
666
+ return error;
479
667
  git_vector_foreach(&backend->packs, i, p) {
480
668
  if ((error = git_pack_foreach_entry(p, cb, data)) != 0)
481
669
  return error;
@@ -488,7 +676,7 @@ static int pack_backend__writepack_append(struct git_odb_writepack *_writepack,
488
676
  {
489
677
  struct pack_writepack *writepack = (struct pack_writepack *)_writepack;
490
678
 
491
- assert(writepack);
679
+ GIT_ASSERT_ARG(writepack);
492
680
 
493
681
  return git_indexer_append(writepack->indexer, data, size, stats);
494
682
  }
@@ -497,16 +685,19 @@ static int pack_backend__writepack_commit(struct git_odb_writepack *_writepack,
497
685
  {
498
686
  struct pack_writepack *writepack = (struct pack_writepack *)_writepack;
499
687
 
500
- assert(writepack);
688
+ GIT_ASSERT_ARG(writepack);
501
689
 
502
690
  return git_indexer_commit(writepack->indexer, stats);
503
691
  }
504
692
 
505
693
  static void pack_backend__writepack_free(struct git_odb_writepack *_writepack)
506
694
  {
507
- struct pack_writepack *writepack = (struct pack_writepack *)_writepack;
695
+ struct pack_writepack *writepack;
508
696
 
509
- assert(writepack);
697
+ if (!_writepack)
698
+ return;
699
+
700
+ writepack = (struct pack_writepack *)_writepack;
510
701
 
511
702
  git_indexer_free(writepack->indexer);
512
703
  git__free(writepack);
@@ -522,7 +713,8 @@ static int pack_backend__writepack(struct git_odb_writepack **out,
522
713
  struct pack_backend *backend;
523
714
  struct pack_writepack *writepack;
524
715
 
525
- assert(out && _backend);
716
+ GIT_ASSERT_ARG(out);
717
+ GIT_ASSERT_ARG(_backend);
526
718
 
527
719
  *out = NULL;
528
720
 
@@ -550,20 +742,99 @@ static int pack_backend__writepack(struct git_odb_writepack **out,
550
742
  return 0;
551
743
  }
552
744
 
745
+ static int get_idx_path(
746
+ git_buf *idx_path,
747
+ struct pack_backend *backend,
748
+ struct git_pack_file *p)
749
+ {
750
+ size_t path_len;
751
+ int error;
752
+
753
+ error = git_path_prettify(idx_path, p->pack_name, backend->pack_folder);
754
+ if (error < 0)
755
+ return error;
756
+ path_len = git_buf_len(idx_path);
757
+ if (path_len <= strlen(".pack") || git__suffixcmp(git_buf_cstr(idx_path), ".pack") != 0)
758
+ return git_odb__error_notfound("packfile does not end in .pack", NULL, 0);
759
+ path_len -= strlen(".pack");
760
+ error = git_buf_splice(idx_path, path_len, strlen(".pack"), ".idx", strlen(".idx"));
761
+ if (error < 0)
762
+ return error;
763
+
764
+ return 0;
765
+ }
766
+
767
+ static int pack_backend__writemidx(git_odb_backend *_backend)
768
+ {
769
+ struct pack_backend *backend;
770
+ git_midx_writer *w = NULL;
771
+ struct git_pack_file *p;
772
+ size_t i;
773
+ int error = 0;
774
+
775
+ GIT_ASSERT_ARG(_backend);
776
+
777
+ backend = (struct pack_backend *)_backend;
778
+
779
+ error = git_midx_writer_new(&w, backend->pack_folder);
780
+ if (error < 0)
781
+ return error;
782
+
783
+ git_vector_foreach(&backend->midx_packs, i, p) {
784
+ git_buf idx_path = GIT_BUF_INIT;
785
+ error = get_idx_path(&idx_path, backend, p);
786
+ if (error < 0)
787
+ goto cleanup;
788
+ error = git_midx_writer_add(w, git_buf_cstr(&idx_path));
789
+ git_buf_dispose(&idx_path);
790
+ if (error < 0)
791
+ goto cleanup;
792
+ }
793
+ git_vector_foreach(&backend->packs, i, p) {
794
+ git_buf idx_path = GIT_BUF_INIT;
795
+ error = get_idx_path(&idx_path, backend, p);
796
+ if (error < 0)
797
+ goto cleanup;
798
+ error = git_midx_writer_add(w, git_buf_cstr(&idx_path));
799
+ git_buf_dispose(&idx_path);
800
+ if (error < 0)
801
+ goto cleanup;
802
+ }
803
+
804
+ /*
805
+ * Invalidate the previous midx before writing the new one.
806
+ */
807
+ error = remove_multi_pack_index(backend);
808
+ if (error < 0)
809
+ goto cleanup;
810
+ error = git_midx_writer_commit(w);
811
+ if (error < 0)
812
+ goto cleanup;
813
+ error = refresh_multi_pack_index(backend);
814
+
815
+ cleanup:
816
+ git_midx_writer_free(w);
817
+ return error;
818
+ }
819
+
553
820
  static void pack_backend__free(git_odb_backend *_backend)
554
821
  {
555
822
  struct pack_backend *backend;
823
+ struct git_pack_file *p;
556
824
  size_t i;
557
825
 
558
- assert(_backend);
826
+ if (!_backend)
827
+ return;
559
828
 
560
829
  backend = (struct pack_backend *)_backend;
561
830
 
562
- for (i = 0; i < backend->packs.length; ++i) {
563
- struct git_pack_file *p = git_vector_get(&backend->packs, i);
831
+ git_vector_foreach(&backend->midx_packs, i, p)
832
+ git_mwindow_put_pack(p);
833
+ git_vector_foreach(&backend->packs, i, p)
564
834
  git_mwindow_put_pack(p);
565
- }
566
835
 
836
+ git_midx_free(backend->midx);
837
+ git_vector_free(&backend->midx_packs);
567
838
  git_vector_free(&backend->packs);
568
839
  git__free(backend->pack_folder);
569
840
  git__free(backend);
@@ -574,7 +845,12 @@ static int pack_backend__alloc(struct pack_backend **out, size_t initial_size)
574
845
  struct pack_backend *backend = git__calloc(1, sizeof(struct pack_backend));
575
846
  GIT_ERROR_CHECK_ALLOC(backend);
576
847
 
848
+ if (git_vector_init(&backend->midx_packs, 0, NULL) < 0) {
849
+ git__free(backend);
850
+ return -1;
851
+ }
577
852
  if (git_vector_init(&backend->packs, initial_size, packfile_sort__cb) < 0) {
853
+ git_vector_free(&backend->midx_packs);
578
854
  git__free(backend);
579
855
  return -1;
580
856
  }
@@ -589,6 +865,7 @@ static int pack_backend__alloc(struct pack_backend **out, size_t initial_size)
589
865
  backend->parent.refresh = &pack_backend__refresh;
590
866
  backend->parent.foreach = &pack_backend__foreach;
591
867
  backend->parent.writepack = &pack_backend__writepack;
868
+ backend->parent.writemidx = &pack_backend__writemidx;
592
869
  backend->parent.freshen = &pack_backend__freshen;
593
870
  backend->parent.free = &pack_backend__free;
594
871