rugged 1.3.1 → 1.9.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 (656) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +34 -2
  3. data/ext/rugged/extconf.rb +6 -3
  4. data/ext/rugged/rugged.c +16 -0
  5. data/ext/rugged/rugged.h +4 -0
  6. data/ext/rugged/rugged_allocator.c +0 -54
  7. data/ext/rugged/rugged_blame.c +2 -0
  8. data/ext/rugged/rugged_blob.c +3 -0
  9. data/ext/rugged/rugged_commit.c +1 -0
  10. data/ext/rugged/rugged_config.c +9 -2
  11. data/ext/rugged/rugged_diff.c +1 -0
  12. data/ext/rugged/rugged_index.c +2 -0
  13. data/ext/rugged/rugged_patch.c +1 -0
  14. data/ext/rugged/rugged_rebase.c +1 -0
  15. data/ext/rugged/rugged_reference.c +1 -0
  16. data/ext/rugged/rugged_remote.c +28 -10
  17. data/ext/rugged/rugged_repo.c +7 -9
  18. data/ext/rugged/rugged_revwalk.c +5 -1
  19. data/ext/rugged/rugged_settings.c +5 -0
  20. data/ext/rugged/rugged_submodule.c +1 -0
  21. data/ext/rugged/rugged_tag.c +1 -0
  22. data/ext/rugged/rugged_tree.c +4 -0
  23. data/lib/rugged/index.rb +1 -1
  24. data/lib/rugged/tree.rb +5 -1
  25. data/lib/rugged/version.rb +1 -1
  26. data/vendor/libgit2/AUTHORS +1 -0
  27. data/vendor/libgit2/CMakeLists.txt +141 -289
  28. data/vendor/libgit2/COPYING +301 -20
  29. data/vendor/libgit2/cmake/AddCFlagIfSupported.cmake +21 -21
  30. data/vendor/libgit2/cmake/AddClarTest.cmake +7 -0
  31. data/vendor/libgit2/cmake/CheckPrototypeDefinitionSafe.cmake +16 -0
  32. data/vendor/libgit2/cmake/DefaultCFlags.cmake +154 -0
  33. data/vendor/libgit2/cmake/EnableWarnings.cmake +13 -13
  34. data/vendor/libgit2/cmake/ExperimentalFeatures.cmake +23 -0
  35. data/vendor/libgit2/cmake/FindCoreFoundation.cmake +13 -13
  36. data/vendor/libgit2/cmake/FindGSSAPI.cmake +171 -287
  37. data/vendor/libgit2/cmake/FindGSSFramework.cmake +13 -13
  38. data/vendor/libgit2/cmake/FindHTTP_Parser.cmake +17 -17
  39. data/vendor/libgit2/cmake/FindIntlIconv.cmake +51 -0
  40. data/vendor/libgit2/cmake/FindLLHTTP.cmake +39 -0
  41. data/vendor/libgit2/cmake/FindLibSSH2.cmake +5 -5
  42. data/vendor/libgit2/cmake/FindPCRE.cmake +12 -13
  43. data/vendor/libgit2/cmake/FindPCRE2.cmake +12 -12
  44. data/vendor/libgit2/cmake/FindPkgLibraries.cmake +19 -19
  45. data/vendor/libgit2/cmake/FindSecurity.cmake +14 -14
  46. data/vendor/libgit2/cmake/FindStatNsec.cmake +12 -18
  47. data/vendor/libgit2/cmake/Findfutimens.cmake +8 -8
  48. data/vendor/libgit2/cmake/FindmbedTLS.cmake +63 -70
  49. data/vendor/libgit2/cmake/IdeSplitSources.cmake +18 -18
  50. data/vendor/libgit2/cmake/PkgBuildConfig.cmake +60 -60
  51. data/vendor/libgit2/cmake/SanitizeBool.cmake +20 -20
  52. data/vendor/libgit2/cmake/SelectGSSAPI.cmake +37 -37
  53. data/vendor/libgit2/cmake/SelectHTTPParser.cmake +34 -0
  54. data/vendor/libgit2/cmake/SelectHTTPSBackend.cmake +129 -101
  55. data/vendor/libgit2/cmake/SelectHashes.cmake +113 -54
  56. data/vendor/libgit2/cmake/SelectRegex.cmake +56 -0
  57. data/vendor/libgit2/cmake/SelectSSH.cmake +46 -0
  58. data/vendor/libgit2/cmake/SelectXdiff.cmake +9 -0
  59. data/vendor/libgit2/cmake/SelectZlib.cmake +38 -0
  60. data/vendor/libgit2/deps/chromium-zlib/CMakeLists.txt +6 -6
  61. data/vendor/libgit2/deps/llhttp/CMakeLists.txt +8 -0
  62. data/vendor/libgit2/deps/llhttp/LICENSE-MIT +22 -0
  63. data/vendor/libgit2/deps/llhttp/api.c +510 -0
  64. data/vendor/libgit2/deps/llhttp/http.c +170 -0
  65. data/vendor/libgit2/deps/llhttp/llhttp.c +10168 -0
  66. data/vendor/libgit2/deps/llhttp/llhttp.h +897 -0
  67. data/vendor/libgit2/deps/ntlmclient/CMakeLists.txt +33 -31
  68. data/vendor/libgit2/deps/ntlmclient/crypt_builtin_md4.c +311 -0
  69. data/vendor/libgit2/deps/ntlmclient/crypt_commoncrypto.c +2 -1
  70. data/vendor/libgit2/deps/ntlmclient/crypt_mbedtls.c +0 -20
  71. data/vendor/libgit2/deps/ntlmclient/crypt_openssl.c +7 -5
  72. data/vendor/libgit2/deps/ntlmclient/ntlm.c +25 -25
  73. data/vendor/libgit2/deps/ntlmclient/ntlm.h +4 -4
  74. data/vendor/libgit2/deps/ntlmclient/ntlmclient.h +2 -2
  75. data/vendor/libgit2/deps/ntlmclient/unicode_builtin.c +5 -4
  76. data/vendor/libgit2/deps/ntlmclient/unicode_iconv.c +2 -1
  77. data/vendor/libgit2/deps/ntlmclient/utf8.h +1176 -721
  78. data/vendor/libgit2/deps/ntlmclient/util.h +11 -0
  79. data/vendor/libgit2/deps/pcre/CMakeLists.txt +89 -88
  80. data/vendor/libgit2/deps/pcre/LICENCE +5 -5
  81. data/vendor/libgit2/deps/pcre/pcre.h +2 -2
  82. data/vendor/libgit2/deps/pcre/pcre_compile.c +6 -3
  83. data/vendor/libgit2/deps/pcre/pcre_exec.c +2 -2
  84. data/vendor/libgit2/deps/winhttp/CMakeLists.txt +14 -16
  85. data/vendor/libgit2/deps/xdiff/CMakeLists.txt +28 -0
  86. data/vendor/libgit2/deps/xdiff/git-xdiff.h +56 -0
  87. data/vendor/libgit2/{src → deps}/xdiff/xdiff.h +15 -15
  88. data/vendor/libgit2/{src → deps}/xdiff/xdiffi.c +152 -125
  89. data/vendor/libgit2/{src → deps}/xdiff/xdiffi.h +2 -4
  90. data/vendor/libgit2/{src → deps}/xdiff/xemit.c +26 -10
  91. data/vendor/libgit2/{src → deps}/xdiff/xhistogram.c +92 -94
  92. data/vendor/libgit2/{src → deps}/xdiff/xinclude.h +1 -12
  93. data/vendor/libgit2/{src → deps}/xdiff/xmacros.h +18 -1
  94. data/vendor/libgit2/{src → deps}/xdiff/xmerge.c +126 -137
  95. data/vendor/libgit2/{src → deps}/xdiff/xpatience.c +26 -46
  96. data/vendor/libgit2/{src → deps}/xdiff/xprepare.c +24 -46
  97. data/vendor/libgit2/{src → deps}/xdiff/xutils.c +36 -8
  98. data/vendor/libgit2/{src → deps}/xdiff/xutils.h +2 -1
  99. data/vendor/libgit2/deps/zlib/CMakeLists.txt +6 -1
  100. data/vendor/libgit2/deps/zlib/LICENSE +22 -0
  101. data/vendor/libgit2/deps/zlib/adler32.c +7 -22
  102. data/vendor/libgit2/deps/zlib/crc32.c +931 -317
  103. data/vendor/libgit2/deps/zlib/crc32.h +9441 -436
  104. data/vendor/libgit2/deps/zlib/deflate.c +428 -453
  105. data/vendor/libgit2/deps/zlib/deflate.h +51 -23
  106. data/vendor/libgit2/deps/zlib/gzguts.h +15 -19
  107. data/vendor/libgit2/deps/zlib/infback.c +19 -31
  108. data/vendor/libgit2/deps/zlib/inffast.c +15 -18
  109. data/vendor/libgit2/deps/zlib/inffast.h +1 -1
  110. data/vendor/libgit2/deps/zlib/inflate.c +75 -110
  111. data/vendor/libgit2/deps/zlib/inflate.h +3 -2
  112. data/vendor/libgit2/deps/zlib/inftrees.c +6 -11
  113. data/vendor/libgit2/deps/zlib/inftrees.h +6 -6
  114. data/vendor/libgit2/deps/zlib/trees.c +294 -380
  115. data/vendor/libgit2/deps/zlib/zconf.h +23 -14
  116. data/vendor/libgit2/deps/zlib/zlib.h +310 -284
  117. data/vendor/libgit2/deps/zlib/zutil.c +20 -46
  118. data/vendor/libgit2/deps/zlib/zutil.h +24 -41
  119. data/vendor/libgit2/include/git2/annotated_commit.h +12 -5
  120. data/vendor/libgit2/include/git2/apply.h +43 -8
  121. data/vendor/libgit2/include/git2/attr.h +28 -6
  122. data/vendor/libgit2/include/git2/blame.h +137 -29
  123. data/vendor/libgit2/include/git2/blob.h +85 -29
  124. data/vendor/libgit2/include/git2/branch.h +25 -16
  125. data/vendor/libgit2/include/git2/buffer.h +24 -82
  126. data/vendor/libgit2/include/git2/cert.h +4 -3
  127. data/vendor/libgit2/include/git2/checkout.h +88 -34
  128. data/vendor/libgit2/include/git2/cherrypick.h +10 -3
  129. data/vendor/libgit2/include/git2/clone.h +28 -12
  130. data/vendor/libgit2/include/git2/commit.h +134 -3
  131. data/vendor/libgit2/include/git2/common.h +172 -59
  132. data/vendor/libgit2/include/git2/config.h +118 -32
  133. data/vendor/libgit2/include/git2/credential.h +32 -3
  134. data/vendor/libgit2/include/git2/credential_helpers.h +2 -0
  135. data/vendor/libgit2/include/git2/deprecated.h +141 -3
  136. data/vendor/libgit2/include/git2/describe.h +20 -3
  137. data/vendor/libgit2/include/git2/diff.h +95 -19
  138. data/vendor/libgit2/include/git2/email.h +10 -30
  139. data/vendor/libgit2/include/git2/errors.h +51 -61
  140. data/vendor/libgit2/include/git2/experimental.h +20 -0
  141. data/vendor/libgit2/include/git2/filter.h +21 -9
  142. data/vendor/libgit2/include/git2/global.h +8 -1
  143. data/vendor/libgit2/include/git2/graph.h +4 -2
  144. data/vendor/libgit2/include/git2/ignore.h +11 -1
  145. data/vendor/libgit2/include/git2/index.h +111 -11
  146. data/vendor/libgit2/include/git2/indexer.h +67 -2
  147. data/vendor/libgit2/include/git2/mailmap.h +7 -1
  148. data/vendor/libgit2/include/git2/merge.h +70 -5
  149. data/vendor/libgit2/include/git2/message.h +4 -2
  150. data/vendor/libgit2/include/git2/net.h +3 -1
  151. data/vendor/libgit2/include/git2/notes.h +9 -6
  152. data/vendor/libgit2/include/git2/object.h +57 -7
  153. data/vendor/libgit2/include/git2/odb.h +156 -33
  154. data/vendor/libgit2/include/git2/odb_backend.h +132 -16
  155. data/vendor/libgit2/include/git2/oid.h +116 -17
  156. data/vendor/libgit2/include/git2/oidarray.h +7 -1
  157. data/vendor/libgit2/include/git2/pack.h +37 -9
  158. data/vendor/libgit2/include/git2/patch.h +10 -3
  159. data/vendor/libgit2/include/git2/pathspec.h +10 -1
  160. data/vendor/libgit2/include/git2/proxy.h +11 -1
  161. data/vendor/libgit2/include/git2/rebase.h +18 -7
  162. data/vendor/libgit2/include/git2/refdb.h +5 -2
  163. data/vendor/libgit2/include/git2/reflog.h +4 -3
  164. data/vendor/libgit2/include/git2/refs.h +11 -8
  165. data/vendor/libgit2/include/git2/refspec.h +14 -4
  166. data/vendor/libgit2/include/git2/remote.h +295 -54
  167. data/vendor/libgit2/include/git2/repository.h +95 -25
  168. data/vendor/libgit2/include/git2/reset.h +18 -5
  169. data/vendor/libgit2/include/git2/revert.h +9 -4
  170. data/vendor/libgit2/include/git2/revparse.h +4 -4
  171. data/vendor/libgit2/include/git2/revwalk.h +7 -3
  172. data/vendor/libgit2/include/git2/signature.h +47 -2
  173. data/vendor/libgit2/include/git2/stash.h +78 -10
  174. data/vendor/libgit2/include/git2/status.h +24 -11
  175. data/vendor/libgit2/include/git2/stdint.h +87 -85
  176. data/vendor/libgit2/include/git2/strarray.h +2 -16
  177. data/vendor/libgit2/include/git2/submodule.h +27 -11
  178. data/vendor/libgit2/include/git2/sys/alloc.h +12 -34
  179. data/vendor/libgit2/include/git2/sys/commit.h +77 -3
  180. data/vendor/libgit2/include/git2/sys/commit_graph.h +110 -59
  181. data/vendor/libgit2/include/git2/sys/config.h +80 -4
  182. data/vendor/libgit2/include/git2/sys/credential.h +4 -3
  183. data/vendor/libgit2/include/git2/sys/diff.h +21 -1
  184. data/vendor/libgit2/include/git2/sys/email.h +7 -0
  185. data/vendor/libgit2/include/git2/sys/errors.h +76 -0
  186. data/vendor/libgit2/include/git2/sys/filter.h +66 -3
  187. data/vendor/libgit2/include/git2/sys/hashsig.h +11 -0
  188. data/vendor/libgit2/include/git2/sys/index.h +3 -2
  189. data/vendor/libgit2/include/git2/sys/mempack.h +32 -2
  190. data/vendor/libgit2/include/git2/sys/merge.h +55 -7
  191. data/vendor/libgit2/include/git2/sys/midx.h +47 -4
  192. data/vendor/libgit2/include/git2/sys/odb_backend.h +10 -9
  193. data/vendor/libgit2/include/git2/sys/openssl.h +8 -1
  194. data/vendor/libgit2/include/git2/sys/path.h +12 -1
  195. data/vendor/libgit2/include/git2/sys/refdb_backend.h +40 -36
  196. data/vendor/libgit2/include/git2/sys/refs.h +3 -2
  197. data/vendor/libgit2/include/git2/sys/remote.h +53 -0
  198. data/vendor/libgit2/include/git2/sys/repository.h +63 -3
  199. data/vendor/libgit2/include/git2/sys/stream.h +26 -3
  200. data/vendor/libgit2/include/git2/sys/transport.h +87 -41
  201. data/vendor/libgit2/include/git2/tag.h +4 -1
  202. data/vendor/libgit2/include/git2/trace.h +9 -3
  203. data/vendor/libgit2/include/git2/transaction.h +3 -2
  204. data/vendor/libgit2/include/git2/transport.h +11 -3
  205. data/vendor/libgit2/include/git2/tree.h +20 -8
  206. data/vendor/libgit2/include/git2/types.h +26 -10
  207. data/vendor/libgit2/include/git2/version.h +63 -6
  208. data/vendor/libgit2/include/git2/worktree.h +30 -8
  209. data/vendor/libgit2/include/git2.h +1 -0
  210. data/vendor/libgit2/src/CMakeLists.txt +203 -420
  211. data/vendor/libgit2/src/README.md +12 -0
  212. data/vendor/libgit2/src/cli/CMakeLists.txt +56 -0
  213. data/vendor/libgit2/src/cli/README.md +26 -0
  214. data/vendor/libgit2/src/{branch.h → cli/cmd.c} +10 -8
  215. data/vendor/libgit2/src/cli/cmd.h +37 -0
  216. data/vendor/libgit2/src/cli/cmd_blame.c +287 -0
  217. data/vendor/libgit2/src/cli/cmd_cat_file.c +202 -0
  218. data/vendor/libgit2/src/cli/cmd_clone.c +190 -0
  219. data/vendor/libgit2/src/cli/cmd_config.c +241 -0
  220. data/vendor/libgit2/src/cli/cmd_hash_object.c +152 -0
  221. data/vendor/libgit2/src/cli/cmd_help.c +85 -0
  222. data/vendor/libgit2/src/cli/cmd_index_pack.c +114 -0
  223. data/vendor/libgit2/src/cli/cmd_init.c +102 -0
  224. data/vendor/libgit2/src/cli/common.c +168 -0
  225. data/vendor/libgit2/src/cli/common.h +63 -0
  226. data/vendor/libgit2/src/cli/error.h +51 -0
  227. data/vendor/libgit2/src/cli/main.c +134 -0
  228. data/vendor/libgit2/src/cli/opt.c +695 -0
  229. data/vendor/libgit2/src/cli/opt.h +367 -0
  230. data/vendor/libgit2/src/cli/opt_usage.c +263 -0
  231. data/vendor/libgit2/src/cli/opt_usage.h +40 -0
  232. data/vendor/libgit2/src/cli/progress.c +395 -0
  233. data/vendor/libgit2/src/cli/progress.h +129 -0
  234. data/vendor/libgit2/src/cli/sighandler.h +20 -0
  235. data/vendor/libgit2/src/cli/unix/sighandler.c +37 -0
  236. data/vendor/libgit2/src/cli/win32/precompiled.h +3 -0
  237. data/vendor/libgit2/src/cli/win32/sighandler.c +37 -0
  238. data/vendor/libgit2/src/libgit2/CMakeLists.txt +140 -0
  239. data/vendor/libgit2/src/{annotated_commit.c → libgit2/annotated_commit.c} +2 -2
  240. data/vendor/libgit2/src/{annotated_commit.h → libgit2/annotated_commit.h} +2 -2
  241. data/vendor/libgit2/src/{apply.c → libgit2/apply.c} +32 -34
  242. data/vendor/libgit2/src/{apply.h → libgit2/apply.h} +2 -2
  243. data/vendor/libgit2/src/{attr.c → libgit2/attr.c} +48 -31
  244. data/vendor/libgit2/src/{attr_file.c → libgit2/attr_file.c} +25 -20
  245. data/vendor/libgit2/src/{attr_file.h → libgit2/attr_file.h} +6 -4
  246. data/vendor/libgit2/src/{attrcache.c → libgit2/attrcache.c} +87 -46
  247. data/vendor/libgit2/src/{attrcache.h → libgit2/attrcache.h} +5 -9
  248. data/vendor/libgit2/src/{blame.c → libgit2/blame.c} +152 -57
  249. data/vendor/libgit2/src/{blame.h → libgit2/blame.h} +1 -0
  250. data/vendor/libgit2/src/{blame_git.c → libgit2/blame_git.c} +1 -2
  251. data/vendor/libgit2/src/{blob.c → libgit2/blob.c} +38 -29
  252. data/vendor/libgit2/src/{blob.h → libgit2/blob.h} +3 -3
  253. data/vendor/libgit2/src/{branch.c → libgit2/branch.c} +164 -118
  254. data/vendor/libgit2/src/libgit2/branch.h +31 -0
  255. data/vendor/libgit2/src/libgit2/buf.c +126 -0
  256. data/vendor/libgit2/src/libgit2/buf.h +50 -0
  257. data/vendor/libgit2/src/{cache.c → libgit2/cache.c} +22 -17
  258. data/vendor/libgit2/src/{cache.h → libgit2/cache.h} +7 -9
  259. data/vendor/libgit2/src/{checkout.c → libgit2/checkout.c} +107 -91
  260. data/vendor/libgit2/src/{checkout.h → libgit2/checkout.h} +0 -2
  261. data/vendor/libgit2/src/{cherrypick.c → libgit2/cherrypick.c} +14 -15
  262. data/vendor/libgit2/src/{clone.c → libgit2/clone.c} +254 -203
  263. data/vendor/libgit2/src/{clone.h → libgit2/clone.h} +4 -1
  264. data/vendor/libgit2/src/{commit.c → libgit2/commit.c} +296 -77
  265. data/vendor/libgit2/src/libgit2/commit.h +87 -0
  266. data/vendor/libgit2/src/{commit_graph.c → libgit2/commit_graph.c} +246 -135
  267. data/vendor/libgit2/src/{commit_graph.h → libgit2/commit_graph.h} +33 -8
  268. data/vendor/libgit2/src/{commit_list.c → libgit2/commit_list.c} +17 -7
  269. data/vendor/libgit2/src/{commit_list.h → libgit2/commit_list.h} +1 -0
  270. data/vendor/libgit2/src/libgit2/common.h +55 -0
  271. data/vendor/libgit2/src/{config.c → libgit2/config.c} +490 -360
  272. data/vendor/libgit2/src/libgit2/config.cmake.in +3 -0
  273. data/vendor/libgit2/src/{config.h → libgit2/config.h} +24 -6
  274. data/vendor/libgit2/src/{config_backend.h → libgit2/config_backend.h} +8 -10
  275. data/vendor/libgit2/src/{config_cache.c → libgit2/config_cache.c} +4 -5
  276. data/vendor/libgit2/src/{config_file.c → libgit2/config_file.c} +212 -183
  277. data/vendor/libgit2/src/libgit2/config_list.c +285 -0
  278. data/vendor/libgit2/src/libgit2/config_list.h +32 -0
  279. data/vendor/libgit2/src/libgit2/config_mem.c +374 -0
  280. data/vendor/libgit2/src/{config_parse.c → libgit2/config_parse.c} +37 -32
  281. data/vendor/libgit2/src/{config_snapshot.c → libgit2/config_snapshot.c} +24 -31
  282. data/vendor/libgit2/src/{crlf.c → libgit2/crlf.c} +24 -21
  283. data/vendor/libgit2/src/{describe.c → libgit2/describe.c} +62 -51
  284. data/vendor/libgit2/src/{diff.c → libgit2/diff.c} +44 -14
  285. data/vendor/libgit2/src/{diff.h → libgit2/diff.h} +8 -10
  286. data/vendor/libgit2/src/{diff_driver.c → libgit2/diff_driver.c} +46 -55
  287. data/vendor/libgit2/src/{diff_driver.h → libgit2/diff_driver.h} +5 -5
  288. data/vendor/libgit2/src/{diff_file.c → libgit2/diff_file.c} +45 -27
  289. data/vendor/libgit2/src/{diff_generate.c → libgit2/diff_generate.c} +70 -20
  290. data/vendor/libgit2/src/{diff_generate.h → libgit2/diff_generate.h} +5 -3
  291. data/vendor/libgit2/src/{diff_parse.c → libgit2/diff_parse.c} +22 -6
  292. data/vendor/libgit2/src/{diff_print.c → libgit2/diff_print.c} +192 -105
  293. data/vendor/libgit2/src/{diff_stats.c → libgit2/diff_stats.c} +40 -29
  294. data/vendor/libgit2/src/libgit2/diff_stats.h +18 -0
  295. data/vendor/libgit2/src/{diff_tform.c → libgit2/diff_tform.c} +49 -16
  296. data/vendor/libgit2/src/{diff_xdiff.c → libgit2/diff_xdiff.c} +4 -8
  297. data/vendor/libgit2/src/{diff_xdiff.h → libgit2/diff_xdiff.h} +1 -1
  298. data/vendor/libgit2/src/{email.c → libgit2/email.c} +58 -40
  299. data/vendor/libgit2/src/{email.h → libgit2/email.h} +1 -1
  300. data/vendor/libgit2/src/{transports/ssh.h → libgit2/experimental.h.in} +3 -4
  301. data/vendor/libgit2/src/{fetch.c → libgit2/fetch.c} +105 -30
  302. data/vendor/libgit2/src/{fetch.h → libgit2/fetch.h} +1 -3
  303. data/vendor/libgit2/src/{fetchhead.c → libgit2/fetchhead.c} +30 -28
  304. data/vendor/libgit2/src/{filter.c → libgit2/filter.c} +132 -58
  305. data/vendor/libgit2/src/{filter.h → libgit2/filter.h} +26 -5
  306. data/vendor/libgit2/src/{win32 → libgit2}/git2.rc +3 -3
  307. data/vendor/libgit2/src/libgit2/grafts.c +270 -0
  308. data/vendor/libgit2/src/libgit2/grafts.h +35 -0
  309. data/vendor/libgit2/src/{graph.c → libgit2/graph.c} +1 -1
  310. data/vendor/libgit2/src/libgit2/hashmap_oid.h +30 -0
  311. data/vendor/libgit2/src/{ident.c → libgit2/ident.c} +20 -20
  312. data/vendor/libgit2/src/{ignore.c → libgit2/ignore.c} +44 -39
  313. data/vendor/libgit2/src/{ignore.h → libgit2/ignore.h} +2 -2
  314. data/vendor/libgit2/src/{index.c → libgit2/index.c} +460 -276
  315. data/vendor/libgit2/src/{index.h → libgit2/index.h} +21 -5
  316. data/vendor/libgit2/src/libgit2/index_map.c +95 -0
  317. data/vendor/libgit2/src/libgit2/index_map.h +28 -0
  318. data/vendor/libgit2/src/{indexer.c → libgit2/indexer.c} +208 -124
  319. data/vendor/libgit2/src/{iterator.c → libgit2/iterator.c} +102 -71
  320. data/vendor/libgit2/src/{iterator.h → libgit2/iterator.h} +8 -5
  321. data/vendor/libgit2/src/libgit2/libgit2.c +268 -0
  322. data/vendor/libgit2/src/{mailmap.c → libgit2/mailmap.c} +39 -37
  323. data/vendor/libgit2/src/{merge.c → libgit2/merge.c} +83 -73
  324. data/vendor/libgit2/src/{merge.h → libgit2/merge.h} +1 -14
  325. data/vendor/libgit2/src/{merge_driver.c → libgit2/merge_driver.c} +4 -4
  326. data/vendor/libgit2/src/{merge_file.c → libgit2/merge_file.c} +13 -5
  327. data/vendor/libgit2/src/{message.c → libgit2/message.c} +21 -10
  328. data/vendor/libgit2/src/{midx.c → libgit2/midx.c} +174 -112
  329. data/vendor/libgit2/src/{midx.h → libgit2/midx.h} +17 -6
  330. data/vendor/libgit2/src/{mwindow.c → libgit2/mwindow.c} +53 -57
  331. data/vendor/libgit2/src/{mwindow.h → libgit2/mwindow.h} +9 -2
  332. data/vendor/libgit2/src/{notes.c → libgit2/notes.c} +29 -37
  333. data/vendor/libgit2/src/{object.c → libgit2/object.c} +166 -35
  334. data/vendor/libgit2/src/{object.h → libgit2/object.h} +17 -2
  335. data/vendor/libgit2/src/{odb.c → libgit2/odb.c} +261 -88
  336. data/vendor/libgit2/src/{odb.h → libgit2/odb.h} +44 -5
  337. data/vendor/libgit2/src/{odb_loose.c → libgit2/odb_loose.c} +192 -134
  338. data/vendor/libgit2/src/{odb_mempack.c → libgit2/odb_mempack.c} +67 -22
  339. data/vendor/libgit2/src/{odb_pack.c → libgit2/odb_pack.c} +162 -89
  340. data/vendor/libgit2/src/{oid.c → libgit2/oid.c} +171 -92
  341. data/vendor/libgit2/src/libgit2/oid.h +284 -0
  342. data/vendor/libgit2/src/libgit2/oidarray.c +89 -0
  343. data/vendor/libgit2/src/{oidarray.h → libgit2/oidarray.h} +5 -1
  344. data/vendor/libgit2/src/{pack-objects.c → libgit2/pack-objects.c} +126 -66
  345. data/vendor/libgit2/src/{pack-objects.h → libgit2/pack-objects.h} +28 -12
  346. data/vendor/libgit2/src/{pack.c → libgit2/pack.c} +146 -111
  347. data/vendor/libgit2/src/{pack.h → libgit2/pack.h} +45 -25
  348. data/vendor/libgit2/src/{parse.c → libgit2/parse.c} +8 -4
  349. data/vendor/libgit2/src/{parse.h → libgit2/parse.h} +1 -1
  350. data/vendor/libgit2/src/{patch.c → libgit2/patch.c} +3 -3
  351. data/vendor/libgit2/src/{patch.h → libgit2/patch.h} +8 -1
  352. data/vendor/libgit2/src/{patch_generate.c → libgit2/patch_generate.c} +51 -16
  353. data/vendor/libgit2/src/{patch_generate.h → libgit2/patch_generate.h} +5 -5
  354. data/vendor/libgit2/src/{patch_parse.c → libgit2/patch_parse.c} +42 -34
  355. data/vendor/libgit2/src/libgit2/path.c +375 -0
  356. data/vendor/libgit2/src/libgit2/path.h +68 -0
  357. data/vendor/libgit2/src/{pathspec.c → libgit2/pathspec.c} +7 -7
  358. data/vendor/libgit2/src/{pathspec.h → libgit2/pathspec.h} +2 -2
  359. data/vendor/libgit2/src/{proxy.c → libgit2/proxy.c} +4 -1
  360. data/vendor/libgit2/src/{proxy.h → libgit2/proxy.h} +1 -1
  361. data/vendor/libgit2/src/{push.c → libgit2/push.c} +116 -60
  362. data/vendor/libgit2/src/{push.h → libgit2/push.h} +5 -16
  363. data/vendor/libgit2/src/{reader.c → libgit2/reader.c} +9 -9
  364. data/vendor/libgit2/src/{reader.h → libgit2/reader.h} +2 -2
  365. data/vendor/libgit2/src/{rebase.c → libgit2/rebase.c} +147 -147
  366. data/vendor/libgit2/src/{refdb_fs.c → libgit2/refdb_fs.c} +639 -254
  367. data/vendor/libgit2/src/{reflog.c → libgit2/reflog.c} +8 -7
  368. data/vendor/libgit2/src/{reflog.h → libgit2/reflog.h} +3 -2
  369. data/vendor/libgit2/src/{refs.c → libgit2/refs.c} +67 -39
  370. data/vendor/libgit2/src/{refs.h → libgit2/refs.h} +8 -3
  371. data/vendor/libgit2/src/{refspec.c → libgit2/refspec.c} +60 -38
  372. data/vendor/libgit2/src/{refspec.h → libgit2/refspec.h} +13 -2
  373. data/vendor/libgit2/src/{remote.c → libgit2/remote.c} +821 -454
  374. data/vendor/libgit2/src/libgit2/remote.h +101 -0
  375. data/vendor/libgit2/src/{repository.c → libgit2/repository.c} +1377 -594
  376. data/vendor/libgit2/src/{repository.h → libgit2/repository.h} +43 -12
  377. data/vendor/libgit2/src/{reset.c → libgit2/reset.c} +8 -5
  378. data/vendor/libgit2/src/{revert.c → libgit2/revert.c} +18 -22
  379. data/vendor/libgit2/src/{revparse.c → libgit2/revparse.c} +76 -44
  380. data/vendor/libgit2/src/{revwalk.c → libgit2/revwalk.c} +48 -19
  381. data/vendor/libgit2/src/{revwalk.h → libgit2/revwalk.h} +3 -3
  382. data/vendor/libgit2/src/{libgit2.c → libgit2/settings.c} +162 -95
  383. data/vendor/libgit2/src/{settings.h → libgit2/settings.h} +6 -2
  384. data/vendor/libgit2/src/{signature.c → libgit2/signature.c} +144 -21
  385. data/vendor/libgit2/src/{signature.h → libgit2/signature.h} +1 -2
  386. data/vendor/libgit2/src/{stash.c → libgit2/stash.c} +243 -68
  387. data/vendor/libgit2/src/{status.c → libgit2/status.c} +5 -2
  388. data/vendor/libgit2/src/{strarray.c → libgit2/strarray.c} +1 -0
  389. data/vendor/libgit2/src/libgit2/strarray.h +25 -0
  390. data/vendor/libgit2/src/{streams → libgit2/streams}/mbedtls.c +62 -67
  391. data/vendor/libgit2/src/{streams → libgit2/streams}/openssl.c +41 -24
  392. data/vendor/libgit2/src/{streams → libgit2/streams}/openssl.h +2 -0
  393. data/vendor/libgit2/src/{streams → libgit2/streams}/openssl_dynamic.c +11 -3
  394. data/vendor/libgit2/src/{streams → libgit2/streams}/openssl_dynamic.h +6 -3
  395. data/vendor/libgit2/src/libgit2/streams/schannel.c +715 -0
  396. data/vendor/libgit2/src/libgit2/streams/schannel.h +28 -0
  397. data/vendor/libgit2/src/libgit2/streams/socket.c +428 -0
  398. data/vendor/libgit2/src/{streams → libgit2/streams}/socket.h +3 -1
  399. data/vendor/libgit2/src/{streams → libgit2/streams}/stransport.c +79 -19
  400. data/vendor/libgit2/src/{streams → libgit2/streams}/tls.c +5 -0
  401. data/vendor/libgit2/src/{submodule.c → libgit2/submodule.c} +279 -220
  402. data/vendor/libgit2/src/{submodule.h → libgit2/submodule.h} +10 -11
  403. data/vendor/libgit2/src/libgit2/sysdir.c +650 -0
  404. data/vendor/libgit2/src/{sysdir.h → libgit2/sysdir.h} +55 -18
  405. data/vendor/libgit2/src/{tag.c → libgit2/tag.c} +74 -43
  406. data/vendor/libgit2/src/{tag.h → libgit2/tag.h} +2 -2
  407. data/vendor/libgit2/src/{trace.c → libgit2/trace.c} +1 -14
  408. data/vendor/libgit2/src/{trace.h → libgit2/trace.h} +5 -22
  409. data/vendor/libgit2/src/{trailer.c → libgit2/trailer.c} +7 -7
  410. data/vendor/libgit2/src/{transaction.c → libgit2/transaction.c} +27 -21
  411. data/vendor/libgit2/src/{transaction.h → libgit2/transaction.h} +4 -1
  412. data/vendor/libgit2/src/{transport.c → libgit2/transport.c} +14 -11
  413. data/vendor/libgit2/src/{transports → libgit2/transports}/auth.c +7 -9
  414. data/vendor/libgit2/src/{transports → libgit2/transports}/auth.h +3 -5
  415. data/vendor/libgit2/src/{transports/auth_negotiate.c → libgit2/transports/auth_gssapi.c} +44 -45
  416. data/vendor/libgit2/src/{transports → libgit2/transports}/auth_negotiate.h +1 -1
  417. data/vendor/libgit2/src/{transports → libgit2/transports}/auth_ntlm.h +1 -2
  418. data/vendor/libgit2/src/{transports/auth_ntlm.c → libgit2/transports/auth_ntlmclient.c} +22 -22
  419. data/vendor/libgit2/src/libgit2/transports/auth_sspi.c +341 -0
  420. data/vendor/libgit2/src/{transports → libgit2/transports}/credential.c +1 -1
  421. data/vendor/libgit2/src/{transports → libgit2/transports}/git.c +16 -19
  422. data/vendor/libgit2/src/{transports → libgit2/transports}/http.c +49 -24
  423. data/vendor/libgit2/src/{transports → libgit2/transports}/http.h +0 -11
  424. data/vendor/libgit2/src/{transports → libgit2/transports}/httpclient.c +188 -134
  425. data/vendor/libgit2/src/{transports → libgit2/transports}/httpclient.h +10 -0
  426. data/vendor/libgit2/src/libgit2/transports/httpparser.c +128 -0
  427. data/vendor/libgit2/src/libgit2/transports/httpparser.h +99 -0
  428. data/vendor/libgit2/src/{transports → libgit2/transports}/local.c +159 -127
  429. data/vendor/libgit2/src/{transports → libgit2/transports}/smart.c +142 -165
  430. data/vendor/libgit2/src/{transports → libgit2/transports}/smart.h +56 -36
  431. data/vendor/libgit2/src/{transports → libgit2/transports}/smart_pkt.c +307 -74
  432. data/vendor/libgit2/src/{transports → libgit2/transports}/smart_protocol.c +297 -97
  433. data/vendor/libgit2/src/libgit2/transports/ssh.c +85 -0
  434. data/vendor/libgit2/src/libgit2/transports/ssh_exec.c +347 -0
  435. data/vendor/libgit2/src/libgit2/transports/ssh_exec.h +26 -0
  436. data/vendor/libgit2/src/{transports/ssh.c → libgit2/transports/ssh_libssh2.c} +414 -268
  437. data/vendor/libgit2/src/libgit2/transports/ssh_libssh2.h +28 -0
  438. data/vendor/libgit2/src/{transports → libgit2/transports}/winhttp.c +101 -75
  439. data/vendor/libgit2/src/{tree-cache.c → libgit2/tree-cache.c} +30 -20
  440. data/vendor/libgit2/src/{tree-cache.h → libgit2/tree-cache.h} +7 -5
  441. data/vendor/libgit2/src/{tree.c → libgit2/tree.c} +128 -110
  442. data/vendor/libgit2/src/{tree.h → libgit2/tree.h} +7 -6
  443. data/vendor/libgit2/src/{worktree.c → libgit2/worktree.c} +160 -121
  444. data/vendor/libgit2/src/{worktree.h → libgit2/worktree.h} +1 -1
  445. data/vendor/libgit2/src/util/CMakeLists.txt +77 -0
  446. data/vendor/libgit2/src/{alloc.c → util/alloc.c} +69 -7
  447. data/vendor/libgit2/src/util/alloc.h +65 -0
  448. data/vendor/libgit2/src/util/allocators/debugalloc.c +73 -0
  449. data/vendor/libgit2/src/util/allocators/debugalloc.h +17 -0
  450. data/vendor/libgit2/src/util/allocators/failalloc.c +32 -0
  451. data/vendor/libgit2/src/util/allocators/failalloc.h +17 -0
  452. data/vendor/libgit2/src/util/allocators/stdalloc.c +37 -0
  453. data/vendor/libgit2/src/{allocators → util/allocators}/stdalloc.h +1 -1
  454. data/vendor/libgit2/src/util/allocators/win32_leakcheck.c +50 -0
  455. data/vendor/libgit2/src/{allocators → util/allocators}/win32_leakcheck.h +1 -1
  456. data/vendor/libgit2/src/{array.h → util/array.h} +25 -19
  457. data/vendor/libgit2/src/{assert_safe.h → util/assert_safe.h} +16 -0
  458. data/vendor/libgit2/src/{cc-compat.h → util/cc-compat.h} +5 -1
  459. data/vendor/libgit2/src/util/ctype_compat.h +70 -0
  460. data/vendor/libgit2/src/{date.c → util/date.c} +35 -33
  461. data/vendor/libgit2/src/util/date.h +45 -0
  462. data/vendor/libgit2/src/util/errors.c +401 -0
  463. data/vendor/libgit2/src/{errors.h → util/errors.h} +22 -19
  464. data/vendor/libgit2/src/{filebuf.c → util/filebuf.c} +35 -30
  465. data/vendor/libgit2/src/{filebuf.h → util/filebuf.h} +21 -8
  466. data/vendor/libgit2/src/{path.c → util/fs_path.c} +591 -615
  467. data/vendor/libgit2/src/{path.h → util/fs_path.h} +257 -181
  468. data/vendor/libgit2/src/{futils.c → util/futils.c} +144 -95
  469. data/vendor/libgit2/src/{futils.h → util/futils.h} +40 -18
  470. data/vendor/libgit2/src/{features.h.in → util/git2_features.h.in} +33 -2
  471. data/vendor/libgit2/src/{common.h → util/git2_util.h} +26 -59
  472. data/vendor/libgit2/src/util/hash/builtin.c +53 -0
  473. data/vendor/libgit2/src/{hash/sha1/openssl.h → util/hash/builtin.h} +6 -6
  474. data/vendor/libgit2/src/{hash/sha1 → util/hash}/collisiondetect.c +3 -3
  475. data/vendor/libgit2/src/{hash/sha1 → util/hash}/collisiondetect.h +3 -3
  476. data/vendor/libgit2/src/util/hash/common_crypto.c +112 -0
  477. data/vendor/libgit2/src/{hash/sha1 → util/hash}/common_crypto.h +11 -3
  478. data/vendor/libgit2/src/util/hash/mbedtls.c +92 -0
  479. data/vendor/libgit2/src/{hash/sha1 → util/hash}/mbedtls.h +14 -4
  480. data/vendor/libgit2/src/util/hash/openssl.c +347 -0
  481. data/vendor/libgit2/src/util/hash/openssl.h +61 -0
  482. data/vendor/libgit2/src/util/hash/rfc6234/sha.h +243 -0
  483. data/vendor/libgit2/src/util/hash/rfc6234/sha224-256.c +601 -0
  484. data/vendor/libgit2/src/util/hash/sha.h +73 -0
  485. data/vendor/libgit2/src/{hash/sha1 → util/hash}/sha1dc/sha1.c +1 -1
  486. data/vendor/libgit2/src/util/hash/win32.c +549 -0
  487. data/vendor/libgit2/src/util/hash/win32.h +60 -0
  488. data/vendor/libgit2/src/util/hash.c +158 -0
  489. data/vendor/libgit2/src/util/hash.h +61 -0
  490. data/vendor/libgit2/src/util/hashmap.h +424 -0
  491. data/vendor/libgit2/src/util/hashmap_str.h +43 -0
  492. data/vendor/libgit2/src/{integer.h → util/integer.h} +3 -1
  493. data/vendor/libgit2/src/{map.h → util/map.h} +1 -1
  494. data/vendor/libgit2/src/util/net.c +1160 -0
  495. data/vendor/libgit2/src/{net.h → util/net.h} +45 -4
  496. data/vendor/libgit2/src/{pool.c → util/pool.c} +1 -1
  497. data/vendor/libgit2/src/{pool.h → util/pool.h} +6 -1
  498. data/vendor/libgit2/src/{posix.c → util/posix.c} +57 -3
  499. data/vendor/libgit2/src/{posix.h → util/posix.h} +26 -1
  500. data/vendor/libgit2/src/{pqueue.h → util/pqueue.h} +3 -3
  501. data/vendor/libgit2/src/util/process.h +222 -0
  502. data/vendor/libgit2/src/util/rand.c +230 -0
  503. data/vendor/libgit2/src/util/rand.h +37 -0
  504. data/vendor/libgit2/src/{regexp.c → util/regexp.c} +5 -5
  505. data/vendor/libgit2/src/{regexp.h → util/regexp.h} +1 -1
  506. data/vendor/libgit2/src/{runtime.c → util/runtime.c} +1 -1
  507. data/vendor/libgit2/src/{runtime.h → util/runtime.h} +1 -1
  508. data/vendor/libgit2/src/{sortedcache.c → util/sortedcache.c} +15 -14
  509. data/vendor/libgit2/src/{sortedcache.h → util/sortedcache.h} +5 -5
  510. data/vendor/libgit2/src/util/staticstr.h +66 -0
  511. data/vendor/libgit2/src/{buffer.c → util/str.c} +159 -153
  512. data/vendor/libgit2/src/util/str.h +357 -0
  513. data/vendor/libgit2/src/util/strlist.c +108 -0
  514. data/vendor/libgit2/src/util/strlist.h +36 -0
  515. data/vendor/libgit2/src/{thread.c → util/thread.c} +1 -1
  516. data/vendor/libgit2/src/{thread.h → util/thread.h} +23 -22
  517. data/vendor/libgit2/src/{tsort.c → util/tsort.c} +1 -1
  518. data/vendor/libgit2/src/{unix → util/unix}/map.c +1 -3
  519. data/vendor/libgit2/src/{unix → util/unix}/posix.h +1 -6
  520. data/vendor/libgit2/src/util/unix/process.c +629 -0
  521. data/vendor/libgit2/src/{unix → util/unix}/realpath.c +24 -8
  522. data/vendor/libgit2/src/{utf8.c → util/utf8.c} +1 -1
  523. data/vendor/libgit2/src/{utf8.h → util/utf8.h} +1 -1
  524. data/vendor/libgit2/src/{util.c → util/util.c} +24 -19
  525. data/vendor/libgit2/src/{util.h → util/util.h} +30 -81
  526. data/vendor/libgit2/src/{varint.h → util/varint.h} +1 -1
  527. data/vendor/libgit2/src/{vector.c → util/vector.c} +3 -3
  528. data/vendor/libgit2/src/{vector.h → util/vector.h} +4 -4
  529. data/vendor/libgit2/src/{wildmatch.h → util/wildmatch.h} +1 -1
  530. data/vendor/libgit2/src/{win32 → util/win32}/dir.h +1 -1
  531. data/vendor/libgit2/src/{win32 → util/win32}/error.c +1 -1
  532. data/vendor/libgit2/src/{win32 → util/win32}/error.h +1 -1
  533. data/vendor/libgit2/src/{win32 → util/win32}/map.c +1 -1
  534. data/vendor/libgit2/src/{win32 → util/win32}/path_w32.c +148 -17
  535. data/vendor/libgit2/src/{win32 → util/win32}/path_w32.h +3 -1
  536. data/vendor/libgit2/src/{win32 → util/win32}/posix.h +1 -2
  537. data/vendor/libgit2/src/{win32 → util/win32}/posix_w32.c +42 -35
  538. data/vendor/libgit2/src/util/win32/precompiled.c +1 -0
  539. data/vendor/libgit2/src/{win32 → util/win32}/precompiled.h +1 -1
  540. data/vendor/libgit2/src/util/win32/process.c +506 -0
  541. data/vendor/libgit2/src/{win32 → util/win32}/thread.h +1 -1
  542. data/vendor/libgit2/src/util/win32/utf-conv.c +144 -0
  543. data/vendor/libgit2/src/util/win32/utf-conv.h +127 -0
  544. data/vendor/libgit2/src/{win32 → util/win32}/w32_buffer.c +2 -3
  545. data/vendor/libgit2/src/{win32 → util/win32}/w32_buffer.h +3 -4
  546. data/vendor/libgit2/src/{win32 → util/win32}/w32_leakcheck.c +1 -1
  547. data/vendor/libgit2/src/{win32 → util/win32}/w32_leakcheck.h +1 -1
  548. data/vendor/libgit2/src/{win32 → util/win32}/w32_util.c +1 -1
  549. data/vendor/libgit2/src/{win32 → util/win32}/w32_util.h +1 -1
  550. data/vendor/libgit2/src/{zstream.c → util/zstream.c} +5 -5
  551. data/vendor/libgit2/src/{zstream.h → util/zstream.h} +5 -5
  552. metadata +431 -362
  553. data/vendor/libgit2/cmake/FindIconv.cmake +0 -45
  554. data/vendor/libgit2/deps/http-parser/CMakeLists.txt +0 -6
  555. data/vendor/libgit2/deps/http-parser/COPYING +0 -23
  556. data/vendor/libgit2/deps/http-parser/http_parser.c +0 -2182
  557. data/vendor/libgit2/deps/http-parser/http_parser.h +0 -305
  558. data/vendor/libgit2/deps/zlib/COPYING +0 -27
  559. data/vendor/libgit2/include/git2/sys/reflog.h +0 -21
  560. data/vendor/libgit2/src/alloc.h +0 -40
  561. data/vendor/libgit2/src/allocators/failalloc.c +0 -92
  562. data/vendor/libgit2/src/allocators/failalloc.h +0 -23
  563. data/vendor/libgit2/src/allocators/stdalloc.c +0 -150
  564. data/vendor/libgit2/src/allocators/win32_leakcheck.c +0 -118
  565. data/vendor/libgit2/src/buffer.h +0 -374
  566. data/vendor/libgit2/src/commit.h +0 -46
  567. data/vendor/libgit2/src/config_entries.c +0 -237
  568. data/vendor/libgit2/src/config_entries.h +0 -24
  569. data/vendor/libgit2/src/config_mem.c +0 -220
  570. data/vendor/libgit2/src/errors.c +0 -238
  571. data/vendor/libgit2/src/hash/sha1/common_crypto.c +0 -57
  572. data/vendor/libgit2/src/hash/sha1/generic.c +0 -300
  573. data/vendor/libgit2/src/hash/sha1/generic.h +0 -19
  574. data/vendor/libgit2/src/hash/sha1/mbedtls.c +0 -46
  575. data/vendor/libgit2/src/hash/sha1/openssl.c +0 -59
  576. data/vendor/libgit2/src/hash/sha1/win32.c +0 -333
  577. data/vendor/libgit2/src/hash/sha1/win32.h +0 -128
  578. data/vendor/libgit2/src/hash/sha1.h +0 -38
  579. data/vendor/libgit2/src/hash.c +0 -110
  580. data/vendor/libgit2/src/hash.h +0 -46
  581. data/vendor/libgit2/src/idxmap.c +0 -157
  582. data/vendor/libgit2/src/idxmap.h +0 -177
  583. data/vendor/libgit2/src/khash.h +0 -615
  584. data/vendor/libgit2/src/libgit2.h +0 -15
  585. data/vendor/libgit2/src/message.h +0 -17
  586. data/vendor/libgit2/src/net.c +0 -540
  587. data/vendor/libgit2/src/netops.c +0 -125
  588. data/vendor/libgit2/src/netops.h +0 -68
  589. data/vendor/libgit2/src/offmap.c +0 -101
  590. data/vendor/libgit2/src/offmap.h +0 -133
  591. data/vendor/libgit2/src/oid.h +0 -51
  592. data/vendor/libgit2/src/oidarray.c +0 -43
  593. data/vendor/libgit2/src/oidmap.c +0 -107
  594. data/vendor/libgit2/src/oidmap.h +0 -128
  595. data/vendor/libgit2/src/remote.h +0 -55
  596. data/vendor/libgit2/src/streams/socket.c +0 -239
  597. data/vendor/libgit2/src/strmap.c +0 -100
  598. data/vendor/libgit2/src/strmap.h +0 -131
  599. data/vendor/libgit2/src/sysdir.c +0 -347
  600. data/vendor/libgit2/src/threadstate.c +0 -84
  601. data/vendor/libgit2/src/threadstate.h +0 -24
  602. data/vendor/libgit2/src/win32/findfile.c +0 -230
  603. data/vendor/libgit2/src/win32/findfile.h +0 -19
  604. data/vendor/libgit2/src/win32/utf-conv.c +0 -146
  605. data/vendor/libgit2/src/win32/utf-conv.h +0 -60
  606. /data/vendor/libgit2/{src → deps}/xdiff/xemit.h +0 -0
  607. /data/vendor/libgit2/{src → deps}/xdiff/xprepare.h +0 -0
  608. /data/vendor/libgit2/{src → deps}/xdiff/xtypes.h +0 -0
  609. /data/vendor/libgit2/src/{win32 → cli/win32}/precompiled.c +0 -0
  610. /data/vendor/libgit2/src/{attr.h → libgit2/attr.h} +0 -0
  611. /data/vendor/libgit2/src/{blame_git.h → libgit2/blame_git.h} +0 -0
  612. /data/vendor/libgit2/src/{config_parse.h → libgit2/config_parse.h} +0 -0
  613. /data/vendor/libgit2/src/{delta.c → libgit2/delta.c} +0 -0
  614. /data/vendor/libgit2/src/{delta.h → libgit2/delta.h} +0 -0
  615. /data/vendor/libgit2/src/{diff_file.h → libgit2/diff_file.h} +0 -0
  616. /data/vendor/libgit2/src/{diff_parse.h → libgit2/diff_parse.h} +0 -0
  617. /data/vendor/libgit2/src/{diff_tform.h → libgit2/diff_tform.h} +0 -0
  618. /data/vendor/libgit2/src/{fetchhead.h → libgit2/fetchhead.h} +0 -0
  619. /data/vendor/libgit2/src/{hashsig.c → libgit2/hashsig.c} +0 -0
  620. /data/vendor/libgit2/src/{indexer.h → libgit2/indexer.h} +0 -0
  621. /data/vendor/libgit2/src/{mailmap.h → libgit2/mailmap.h} +0 -0
  622. /data/vendor/libgit2/src/{merge_driver.h → libgit2/merge_driver.h} +0 -0
  623. /data/vendor/libgit2/src/{notes.h → libgit2/notes.h} +0 -0
  624. /data/vendor/libgit2/src/{object_api.c → libgit2/object_api.c} +0 -0
  625. /data/vendor/libgit2/src/{patch_parse.h → libgit2/patch_parse.h} +0 -0
  626. /data/vendor/libgit2/src/{refdb.c → libgit2/refdb.c} +0 -0
  627. /data/vendor/libgit2/src/{refdb.h → libgit2/refdb.h} +0 -0
  628. /data/vendor/libgit2/src/{repo_template.h → libgit2/repo_template.h} +0 -0
  629. /data/vendor/libgit2/src/{status.h → libgit2/status.h} +0 -0
  630. /data/vendor/libgit2/src/{stream.h → libgit2/stream.h} +0 -0
  631. /data/vendor/libgit2/src/{streams → libgit2/streams}/mbedtls.h +0 -0
  632. /data/vendor/libgit2/src/{streams → libgit2/streams}/openssl_legacy.c +0 -0
  633. /data/vendor/libgit2/src/{streams → libgit2/streams}/openssl_legacy.h +0 -0
  634. /data/vendor/libgit2/src/{streams → libgit2/streams}/registry.c +0 -0
  635. /data/vendor/libgit2/src/{streams → libgit2/streams}/registry.h +0 -0
  636. /data/vendor/libgit2/src/{streams → libgit2/streams}/stransport.h +0 -0
  637. /data/vendor/libgit2/src/{streams → libgit2/streams}/tls.h +0 -0
  638. /data/vendor/libgit2/src/{transports → libgit2/transports}/credential_helpers.c +0 -0
  639. /data/vendor/libgit2/src/{userdiff.h → libgit2/userdiff.h} +0 -0
  640. /data/vendor/libgit2/src/{bitvec.h → util/bitvec.h} +0 -0
  641. /data/vendor/libgit2/src/{hash/sha1 → util/hash}/sha1dc/sha1.h +0 -0
  642. /data/vendor/libgit2/src/{hash/sha1 → util/hash}/sha1dc/ubc_check.c +0 -0
  643. /data/vendor/libgit2/src/{hash/sha1 → util/hash}/sha1dc/ubc_check.h +0 -0
  644. /data/vendor/libgit2/src/{pqueue.c → util/pqueue.c} +0 -0
  645. /data/vendor/libgit2/src/{strnlen.h → util/strnlen.h} +0 -0
  646. /data/vendor/libgit2/src/{unix → util/unix}/pthread.h +0 -0
  647. /data/vendor/libgit2/src/{varint.c → util/varint.c} +0 -0
  648. /data/vendor/libgit2/src/{wildmatch.c → util/wildmatch.c} +0 -0
  649. /data/vendor/libgit2/src/{win32 → util/win32}/dir.c +0 -0
  650. /data/vendor/libgit2/src/{win32 → util/win32}/mingw-compat.h +0 -0
  651. /data/vendor/libgit2/src/{win32 → util/win32}/msvc-compat.h +0 -0
  652. /data/vendor/libgit2/src/{win32 → util/win32}/reparse.h +0 -0
  653. /data/vendor/libgit2/src/{win32 → util/win32}/thread.c +0 -0
  654. /data/vendor/libgit2/src/{win32 → util/win32}/version.h +0 -0
  655. /data/vendor/libgit2/src/{win32 → util/win32}/w32_common.h +0 -0
  656. /data/vendor/libgit2/src/{win32 → util/win32}/win32-compat.h +0 -0
@@ -12,8 +12,10 @@
12
12
  #include "git2/object.h"
13
13
  #include "git2/sys/repository.h"
14
14
 
15
+ #include "buf.h"
15
16
  #include "common.h"
16
17
  #include "commit.h"
18
+ #include "grafts.h"
17
19
  #include "tag.h"
18
20
  #include "blob.h"
19
21
  #include "futils.h"
@@ -31,13 +33,13 @@
31
33
  #include "annotated_commit.h"
32
34
  #include "submodule.h"
33
35
  #include "worktree.h"
34
-
35
- #include "strmap.h"
36
+ #include "path.h"
36
37
 
37
38
  #ifdef GIT_WIN32
38
39
  # include "win32/w32_util.h"
39
40
  #endif
40
41
 
42
+ bool git_repository__validate_ownership = true;
41
43
  bool git_repository__fsync_gitdir = false;
42
44
 
43
45
  static const struct {
@@ -59,11 +61,14 @@ static const struct {
59
61
  { GIT_REPOSITORY_ITEM_COMMONDIR, GIT_REPOSITORY_ITEM_GITDIR, "hooks", true },
60
62
  { GIT_REPOSITORY_ITEM_COMMONDIR, GIT_REPOSITORY_ITEM_GITDIR, "logs", true },
61
63
  { GIT_REPOSITORY_ITEM_GITDIR, GIT_REPOSITORY_ITEM__LAST, "modules", true },
62
- { GIT_REPOSITORY_ITEM_COMMONDIR, GIT_REPOSITORY_ITEM_GITDIR, "worktrees", true }
64
+ { GIT_REPOSITORY_ITEM_COMMONDIR, GIT_REPOSITORY_ITEM_GITDIR, "worktrees", true },
65
+ { GIT_REPOSITORY_ITEM_GITDIR, GIT_REPOSITORY_ITEM_GITDIR, "config.worktree", false }
63
66
  };
64
67
 
65
68
  static int check_repositoryformatversion(int *version, git_config *config);
66
69
  static int check_extensions(git_config *config, int version);
70
+ static int load_global_config(git_config **config, bool use_env);
71
+ static int load_objectformat(git_repository *repo, git_config *config);
67
72
 
68
73
  #define GIT_COMMONDIR_FILE "commondir"
69
74
  #define GIT_GITDIR_FILE "gitdir"
@@ -72,16 +77,16 @@ static int check_extensions(git_config *config, int version);
72
77
 
73
78
  #define GIT_BRANCH_DEFAULT "master"
74
79
 
75
- #define GIT_REPO_VERSION 0
76
- #define GIT_REPO_MAX_VERSION 1
80
+ #define GIT_REPO_VERSION_DEFAULT 0
81
+ #define GIT_REPO_VERSION_MAX 1
77
82
 
78
- git_buf git_repository__reserved_names_win32[] = {
83
+ git_str git_repository__reserved_names_win32[] = {
79
84
  { DOT_GIT, 0, CONST_STRLEN(DOT_GIT) },
80
85
  { GIT_DIR_SHORTNAME, 0, CONST_STRLEN(GIT_DIR_SHORTNAME) }
81
86
  };
82
87
  size_t git_repository__reserved_names_win32_len = 2;
83
88
 
84
- git_buf git_repository__reserved_names_posix[] = {
89
+ git_str git_repository__reserved_names_posix[] = {
85
90
  { DOT_GIT, 0, CONST_STRLEN(DOT_GIT) },
86
91
  };
87
92
  size_t git_repository__reserved_names_posix_len = 1;
@@ -147,6 +152,10 @@ int git_repository__cleanup(git_repository *repo)
147
152
  git_repository_submodule_cache_clear(repo);
148
153
  git_cache_clear(&repo->objects);
149
154
  git_attr_cache_flush(repo);
155
+ git_grafts_free(repo->grafts);
156
+ repo->grafts = NULL;
157
+ git_grafts_free(repo->shallow_grafts);
158
+ repo->shallow_grafts = NULL;
150
159
 
151
160
  set_config(repo, NULL);
152
161
  set_index(repo, NULL);
@@ -171,7 +180,7 @@ void git_repository_free(git_repository *repo)
171
180
  repo->diff_drivers = NULL;
172
181
 
173
182
  for (i = 0; i < repo->reserved_names.size; i++)
174
- git_buf_dispose(git_array_get(repo->reserved_names, i));
183
+ git_str_dispose(git_array_get(repo->reserved_names, i));
175
184
  git_array_clear(repo->reserved_names);
176
185
 
177
186
  git__free(repo->gitlink);
@@ -187,18 +196,30 @@ void git_repository_free(git_repository *repo)
187
196
  }
188
197
 
189
198
  /* Check if we have a separate commondir (e.g. we have a worktree) */
190
- static int lookup_commondir(bool *separate, git_buf *commondir, git_buf *repository_path)
199
+ static int lookup_commondir(
200
+ bool *separate,
201
+ git_str *commondir,
202
+ git_str *repository_path,
203
+ uint32_t flags)
191
204
  {
192
- git_buf common_link = GIT_BUF_INIT;
205
+ git_str common_link = GIT_STR_INIT;
193
206
  int error;
194
207
 
208
+ /* Environment variable overrides configuration */
209
+ if ((flags & GIT_REPOSITORY_OPEN_FROM_ENV)) {
210
+ error = git__getenv(commondir, "GIT_COMMON_DIR");
211
+
212
+ if (!error || error != GIT_ENOTFOUND)
213
+ goto done;
214
+ }
215
+
195
216
  /*
196
217
  * If there's no commondir file, the repository path is the
197
218
  * common path, but it needs a trailing slash.
198
219
  */
199
- if (!git_path_contains_file(repository_path, GIT_COMMONDIR_FILE)) {
200
- if ((error = git_buf_set(commondir, repository_path->ptr, repository_path->size)) == 0)
201
- error = git_path_to_dir(commondir);
220
+ if (!git_fs_path_contains_file(repository_path, GIT_COMMONDIR_FILE)) {
221
+ if ((error = git_str_set(commondir, repository_path->ptr, repository_path->size)) == 0)
222
+ error = git_fs_path_to_dir(commondir);
202
223
 
203
224
  *separate = false;
204
225
  goto done;
@@ -206,28 +227,27 @@ static int lookup_commondir(bool *separate, git_buf *commondir, git_buf *reposit
206
227
 
207
228
  *separate = true;
208
229
 
209
- if ((error = git_buf_joinpath(&common_link, repository_path->ptr, GIT_COMMONDIR_FILE)) < 0 ||
230
+ if ((error = git_str_joinpath(&common_link, repository_path->ptr, GIT_COMMONDIR_FILE)) < 0 ||
210
231
  (error = git_futils_readbuffer(&common_link, common_link.ptr)) < 0)
211
232
  goto done;
212
233
 
213
- git_buf_rtrim(&common_link);
214
- if (git_path_is_relative(common_link.ptr)) {
215
- if ((error = git_buf_joinpath(commondir, repository_path->ptr, common_link.ptr)) < 0)
234
+ git_str_rtrim(&common_link);
235
+ if (git_fs_path_is_relative(common_link.ptr)) {
236
+ if ((error = git_str_joinpath(commondir, repository_path->ptr, common_link.ptr)) < 0)
216
237
  goto done;
217
238
  } else {
218
- git_buf_swap(commondir, &common_link);
239
+ git_str_swap(commondir, &common_link);
219
240
  }
220
241
 
221
- git_buf_dispose(&common_link);
222
-
223
242
  /* Make sure the commondir path always has a trailing slash */
224
- error = git_path_prettify_dir(commondir, commondir->ptr, NULL);
243
+ error = git_fs_path_prettify_dir(commondir, commondir->ptr, NULL);
225
244
 
226
245
  done:
246
+ git_str_dispose(&common_link);
227
247
  return error;
228
248
  }
229
249
 
230
- GIT_INLINE(int) validate_repo_path(git_buf *path)
250
+ GIT_INLINE(int) validate_repo_path(git_str *path)
231
251
  {
232
252
  /*
233
253
  * The longest static path in a repository (or commondir) is the
@@ -237,10 +257,10 @@ GIT_INLINE(int) validate_repo_path(git_buf *path)
237
257
  */
238
258
  static size_t suffix_len =
239
259
  CONST_STRLEN("objects/pack/pack-.pack.lock") +
240
- GIT_OID_HEXSZ;
260
+ GIT_OID_MAX_HEXSIZE;
241
261
 
242
- return git_path_validate_filesystem_with_suffix(
243
- path->ptr, path->size, suffix_len);
262
+ return git_fs_path_validate_str_length_with_suffix(
263
+ path, suffix_len);
244
264
  }
245
265
 
246
266
  /*
@@ -248,24 +268,29 @@ GIT_INLINE(int) validate_repo_path(git_buf *path)
248
268
  *
249
269
  * Open a repository object from its path
250
270
  */
251
- static int is_valid_repository_path(bool *out, git_buf *repository_path, git_buf *common_path)
271
+ static int is_valid_repository_path(
272
+ bool *out,
273
+ git_str *repository_path,
274
+ git_str *common_path,
275
+ uint32_t flags)
252
276
  {
253
277
  bool separate_commondir = false;
254
278
  int error;
255
279
 
256
280
  *out = false;
257
281
 
258
- if ((error = lookup_commondir(&separate_commondir, common_path, repository_path)) < 0)
282
+ if ((error = lookup_commondir(&separate_commondir,
283
+ common_path, repository_path, flags)) < 0)
259
284
  return error;
260
285
 
261
286
  /* Ensure HEAD file exists */
262
- if (git_path_contains_file(repository_path, GIT_HEAD_FILE) == false)
287
+ if (git_fs_path_contains_file(repository_path, GIT_HEAD_FILE) == false)
263
288
  return 0;
264
289
 
265
290
  /* Check files in common dir */
266
- if (git_path_contains_dir(common_path, GIT_OBJECTS_DIR) == false)
291
+ if (git_fs_path_contains_dir(common_path, GIT_OBJECTS_DIR) == false)
267
292
  return 0;
268
- if (git_path_contains_dir(common_path, GIT_REFS_DIR) == false)
293
+ if (git_fs_path_contains_dir(common_path, GIT_REFS_DIR) == false)
269
294
  return 0;
270
295
 
271
296
  /* Ensure the repo (and commondir) are valid paths */
@@ -303,19 +328,34 @@ on_error:
303
328
  return NULL;
304
329
  }
305
330
 
306
- int git_repository_new(git_repository **out)
331
+ int git_repository__new(git_repository **out, git_oid_t oid_type)
307
332
  {
308
333
  git_repository *repo;
309
334
 
310
335
  *out = repo = repository_alloc();
311
336
  GIT_ERROR_CHECK_ALLOC(repo);
312
337
 
338
+ GIT_ASSERT_ARG(git_oid_type_is_valid(oid_type));
339
+
313
340
  repo->is_bare = 1;
314
341
  repo->is_worktree = 0;
342
+ repo->oid_type = oid_type;
315
343
 
316
344
  return 0;
317
345
  }
318
346
 
347
+ #ifdef GIT_EXPERIMENTAL_SHA256
348
+ int git_repository_new(git_repository **out, git_repository_new_options *opts)
349
+ {
350
+ return git_repository__new(out, opts && opts->oid_type ? opts->oid_type : GIT_OID_DEFAULT);
351
+ }
352
+ #else
353
+ int git_repository_new(git_repository** out)
354
+ {
355
+ return git_repository__new(out, GIT_OID_SHA1);
356
+ }
357
+ #endif
358
+
319
359
  static int load_config_data(git_repository *repo, const git_config *config)
320
360
  {
321
361
  int is_bare;
@@ -333,19 +373,42 @@ static int load_config_data(git_repository *repo, const git_config *config)
333
373
  return 0;
334
374
  }
335
375
 
336
- static int load_workdir(git_repository *repo, git_config *config, git_buf *parent_path)
337
- {
376
+ static int load_workdir(
377
+ git_repository *repo,
378
+ git_config *config,
379
+ git_str *parent_path)
380
+ {
381
+ git_config_entry *ce = NULL;
382
+ git_str worktree = GIT_STR_INIT;
383
+ git_str path = GIT_STR_INIT;
384
+ git_str workdir_env = GIT_STR_INIT;
385
+ const char *value = NULL;
338
386
  int error;
339
- git_config_entry *ce;
340
- git_buf worktree = GIT_BUF_INIT;
341
- git_buf path = GIT_BUF_INIT;
342
387
 
343
388
  if (repo->is_bare)
344
389
  return 0;
345
390
 
346
- if ((error = git_config__lookup_entry(
347
- &ce, config, "core.worktree", false)) < 0)
348
- return error;
391
+ /* Environment variables are preferred */
392
+ if (repo->use_env) {
393
+ error = git__getenv(&workdir_env, "GIT_WORK_TREE");
394
+
395
+ if (error == 0)
396
+ value = workdir_env.ptr;
397
+ else if (error == GIT_ENOTFOUND)
398
+ error = 0;
399
+ else
400
+ goto cleanup;
401
+ }
402
+
403
+ /* Examine configuration values if necessary */
404
+ if (!value) {
405
+ if ((error = git_config__lookup_entry(&ce, config,
406
+ "core.worktree", false)) < 0)
407
+ return error;
408
+
409
+ if (ce && ce->value)
410
+ value = ce->value;
411
+ }
349
412
 
350
413
  if (repo->is_worktree) {
351
414
  char *gitlink = git_worktree__read_link(repo->gitdir, GIT_GITDIR_FILE);
@@ -354,38 +417,44 @@ static int load_workdir(git_repository *repo, git_config *config, git_buf *paren
354
417
  goto cleanup;
355
418
  }
356
419
 
357
- git_buf_attach(&worktree, gitlink, 0);
420
+ git_str_attach(&worktree, gitlink, 0);
358
421
 
359
- if ((git_path_dirname_r(&worktree, worktree.ptr)) < 0 ||
360
- git_path_to_dir(&worktree) < 0) {
422
+ if ((git_fs_path_dirname_r(&worktree, worktree.ptr)) < 0 ||
423
+ git_fs_path_to_dir(&worktree) < 0) {
361
424
  error = -1;
362
425
  goto cleanup;
363
426
  }
364
427
 
365
- repo->workdir = git_buf_detach(&worktree);
366
- }
367
- else if (ce && ce->value) {
368
- if ((error = git_path_prettify_dir(
369
- &worktree, ce->value, repo->gitdir)) < 0)
428
+ repo->workdir = git_str_detach(&worktree);
429
+ } else if (value) {
430
+ if (!*value) {
431
+ git_error_set(GIT_ERROR_NET, "working directory cannot be set to empty path");
432
+ error = -1;
370
433
  goto cleanup;
434
+ }
371
435
 
372
- repo->workdir = git_buf_detach(&worktree);
373
- }
374
- else if (parent_path && git_path_isdir(parent_path->ptr))
375
- repo->workdir = git_buf_detach(parent_path);
376
- else {
377
- if (git_path_dirname_r(&worktree, repo->gitdir) < 0 ||
378
- git_path_to_dir(&worktree) < 0) {
436
+ if ((error = git_fs_path_prettify_dir(&worktree,
437
+ value, repo->gitdir)) < 0)
438
+ goto cleanup;
439
+
440
+ repo->workdir = git_str_detach(&worktree);
441
+ } else if (parent_path && git_fs_path_isdir(parent_path->ptr)) {
442
+ repo->workdir = git_str_detach(parent_path);
443
+ } else {
444
+ if (git_fs_path_dirname_r(&worktree, repo->gitdir) < 0 ||
445
+ git_fs_path_to_dir(&worktree) < 0) {
379
446
  error = -1;
380
447
  goto cleanup;
381
448
  }
382
449
 
383
- repo->workdir = git_buf_detach(&worktree);
450
+ repo->workdir = git_str_detach(&worktree);
384
451
  }
385
452
 
386
453
  GIT_ERROR_CHECK_ALLOC(repo->workdir);
454
+
387
455
  cleanup:
388
- git_buf_dispose(&path);
456
+ git_str_dispose(&path);
457
+ git_str_dispose(&workdir_env);
389
458
  git_config_entry_free(ce);
390
459
  return error;
391
460
  }
@@ -394,7 +463,7 @@ cleanup:
394
463
  * This function returns furthest offset into path where a ceiling dir
395
464
  * is found, so we can stop processing the path at that point.
396
465
  *
397
- * Note: converting this to use git_bufs instead of GIT_PATH_MAX buffers on
466
+ * Note: converting this to use git_strs instead of GIT_PATH_MAX buffers on
398
467
  * the stack could remove directories name limits, but at the cost of doing
399
468
  * repeated malloc/frees inside the loop below, so let's not do it now.
400
469
  */
@@ -409,7 +478,7 @@ static size_t find_ceiling_dir_offset(
409
478
 
410
479
  GIT_ASSERT_ARG(path);
411
480
 
412
- min_len = (size_t)(git_path_root(path) + 1);
481
+ min_len = (size_t)(git_fs_path_root(path) + 1);
413
482
 
414
483
  if (ceiling_directories == NULL || min_len == 0)
415
484
  return min_len;
@@ -418,7 +487,7 @@ static size_t find_ceiling_dir_offset(
418
487
  for (sep = ceil; *sep && *sep != GIT_PATH_LIST_SEPARATOR; sep++);
419
488
  len = sep - ceil;
420
489
 
421
- if (len == 0 || len >= sizeof(buf) || git_path_root(ceil) == -1)
490
+ if (len == 0 || len >= sizeof(buf) || git_fs_path_root(ceil) == -1)
422
491
  continue;
423
492
 
424
493
  strncpy(buf, ceil, len);
@@ -447,10 +516,10 @@ static size_t find_ceiling_dir_offset(
447
516
  * it points to. Before calling, set `path_out` to the base directory that
448
517
  * should be used if the contents of `file_path` are a relative path.
449
518
  */
450
- static int read_gitfile(git_buf *path_out, const char *file_path)
519
+ static int read_gitfile(git_str *path_out, const char *file_path)
451
520
  {
452
521
  int error = 0;
453
- git_buf file = GIT_BUF_INIT;
522
+ git_str file = GIT_STR_INIT;
454
523
  size_t prefix_len = strlen(GIT_FILE_CONTENT_PREFIX);
455
524
 
456
525
  GIT_ASSERT_ARG(path_out);
@@ -459,41 +528,222 @@ static int read_gitfile(git_buf *path_out, const char *file_path)
459
528
  if (git_futils_readbuffer(&file, file_path) < 0)
460
529
  return -1;
461
530
 
462
- git_buf_rtrim(&file);
531
+ git_str_rtrim(&file);
463
532
  /* apparently on Windows, some people use backslashes in paths */
464
- git_path_mkposix(file.ptr);
533
+ git_fs_path_mkposix(file.ptr);
465
534
 
466
- if (git_buf_len(&file) <= prefix_len ||
467
- memcmp(git_buf_cstr(&file), GIT_FILE_CONTENT_PREFIX, prefix_len) != 0)
535
+ if (git_str_len(&file) <= prefix_len ||
536
+ memcmp(git_str_cstr(&file), GIT_FILE_CONTENT_PREFIX, prefix_len) != 0)
468
537
  {
469
538
  git_error_set(GIT_ERROR_REPOSITORY,
470
539
  "the `.git` file at '%s' is malformed", file_path);
471
540
  error = -1;
472
541
  }
473
- else if ((error = git_path_dirname_r(path_out, file_path)) >= 0) {
474
- const char *gitlink = git_buf_cstr(&file) + prefix_len;
542
+ else if ((error = git_fs_path_dirname_r(path_out, file_path)) >= 0) {
543
+ const char *gitlink = git_str_cstr(&file) + prefix_len;
475
544
  while (*gitlink && git__isspace(*gitlink)) gitlink++;
476
545
 
477
- error = git_path_prettify_dir(
478
- path_out, gitlink, git_buf_cstr(path_out));
546
+ error = git_fs_path_prettify_dir(
547
+ path_out, gitlink, git_str_cstr(path_out));
479
548
  }
480
549
 
481
- git_buf_dispose(&file);
550
+ git_str_dispose(&file);
482
551
  return error;
483
552
  }
484
553
 
485
- static int find_repo(
486
- git_buf *gitdir_path,
487
- git_buf *workdir_path,
488
- git_buf *gitlink_path,
489
- git_buf *commondir_path,
554
+ typedef struct {
555
+ const char *repo_path;
556
+ git_str tmp;
557
+ bool *is_safe;
558
+ } validate_ownership_data;
559
+
560
+ static int validate_ownership_cb(const git_config_entry *entry, void *payload)
561
+ {
562
+ validate_ownership_data *data = payload;
563
+ const char *test_path;
564
+
565
+ if (strcmp(entry->value, "") == 0) {
566
+ *data->is_safe = false;
567
+ } else if (strcmp(entry->value, "*") == 0) {
568
+ *data->is_safe = true;
569
+ } else {
570
+ if (git_str_sets(&data->tmp, entry->value) < 0)
571
+ return -1;
572
+
573
+ if (!git_fs_path_is_root(data->tmp.ptr)) {
574
+ /* Input must not have trailing backslash. */
575
+ if (!data->tmp.size ||
576
+ data->tmp.ptr[data->tmp.size - 1] == '/')
577
+ return 0;
578
+
579
+ if (git_fs_path_to_dir(&data->tmp) < 0)
580
+ return -1;
581
+ }
582
+
583
+ test_path = data->tmp.ptr;
584
+
585
+ /*
586
+ * Git - and especially, Git for Windows - does some
587
+ * truly bizarre things with paths that start with a
588
+ * forward slash; and expects you to escape that with
589
+ * `%(prefix)`. This syntax generally means to add the
590
+ * prefix that Git was installed to (eg `/usr/local`)
591
+ * unless it's an absolute path, in which case the
592
+ * leading `%(prefix)/` is just removed. And Git for
593
+ * Windows expects you to use this syntax for absolute
594
+ * Unix-style paths (in "Git Bash" or Windows Subsystem
595
+ * for Linux).
596
+ *
597
+ * Worse, the behavior used to be that a leading `/` was
598
+ * not absolute. It would indicate that Git for Windows
599
+ * should add the prefix. So `//` is required for absolute
600
+ * Unix-style paths. Yes, this is truly horrifying.
601
+ *
602
+ * Emulate that behavior, I guess, but only for absolute
603
+ * paths. We won't deal with the Git install prefix. Also,
604
+ * give WSL users an escape hatch where they don't have to
605
+ * think about this and can use the literal path that the
606
+ * filesystem APIs provide (`//wsl.localhost/...`).
607
+ */
608
+ if (strncmp(test_path, "%(prefix)//", strlen("%(prefix)//")) == 0)
609
+ test_path += strlen("%(prefix)/");
610
+
611
+ if (strcmp(test_path, data->repo_path) == 0)
612
+ *data->is_safe = true;
613
+ }
614
+
615
+ return 0;
616
+ }
617
+
618
+ static int validate_ownership_config(
619
+ bool *is_safe,
620
+ const char *path,
621
+ bool use_env)
622
+ {
623
+ validate_ownership_data ownership_data = {
624
+ path, GIT_STR_INIT, is_safe
625
+ };
626
+ git_config *config;
627
+ int error;
628
+
629
+ if (load_global_config(&config, use_env) != 0)
630
+ return 0;
631
+
632
+ error = git_config_get_multivar_foreach(config,
633
+ "safe.directory", NULL,
634
+ validate_ownership_cb,
635
+ &ownership_data);
636
+
637
+ if (error == GIT_ENOTFOUND)
638
+ error = 0;
639
+
640
+ git_config_free(config);
641
+ git_str_dispose(&ownership_data.tmp);
642
+
643
+ return error;
644
+ }
645
+
646
+ static int validate_ownership_path(bool *is_safe, const char *path)
647
+ {
648
+ git_fs_path_owner_t owner_level =
649
+ GIT_FS_PATH_OWNER_CURRENT_USER |
650
+ GIT_FS_PATH_USER_IS_ADMINISTRATOR |
651
+ GIT_FS_PATH_OWNER_RUNNING_SUDO;
652
+ int error = 0;
653
+
654
+ if (path)
655
+ error = git_fs_path_owner_is(is_safe, path, owner_level);
656
+
657
+ if (error == GIT_ENOTFOUND) {
658
+ *is_safe = true;
659
+ error = 0;
660
+ } else if (error == GIT_EINVALID) {
661
+ *is_safe = false;
662
+ error = 0;
663
+ }
664
+
665
+ return error;
666
+ }
667
+
668
+ static int validate_ownership(git_repository *repo)
669
+ {
670
+ const char *validation_paths[3] = { NULL }, *path;
671
+ size_t validation_len = 0, i;
672
+ bool is_safe = false;
673
+ int error = 0;
674
+
675
+ /*
676
+ * If there's a worktree, validate the permissions to it *and*
677
+ * the git directory, and use the worktree as the configuration
678
+ * key for allowlisting the directory. In a bare setup, only
679
+ * look at the gitdir and use that as the allowlist. So we
680
+ * examine all `validation_paths` but use only the first as
681
+ * the configuration lookup.
682
+ */
683
+
684
+ if (repo->workdir)
685
+ validation_paths[validation_len++] = repo->workdir;
686
+
687
+ if (repo->gitlink)
688
+ validation_paths[validation_len++] = repo->gitlink;
689
+
690
+ validation_paths[validation_len++] = repo->gitdir;
691
+
692
+ for (i = 0; i < validation_len; i++) {
693
+ path = validation_paths[i];
694
+
695
+ if ((error = validate_ownership_path(&is_safe, path)) < 0)
696
+ goto done;
697
+
698
+ if (!is_safe)
699
+ break;
700
+ }
701
+
702
+ if (is_safe ||
703
+ (error = validate_ownership_config(
704
+ &is_safe, validation_paths[0], repo->use_env)) < 0)
705
+ goto done;
706
+
707
+ if (!is_safe) {
708
+ size_t path_len = git_fs_path_is_root(path) ?
709
+ strlen(path) : git_fs_path_dirlen(path);
710
+
711
+ git_error_set(GIT_ERROR_CONFIG,
712
+ "repository path '%.*s' is not owned by current user",
713
+ (int)min(path_len, INT_MAX), path);
714
+ error = GIT_EOWNER;
715
+ }
716
+
717
+ done:
718
+ return error;
719
+ }
720
+
721
+ struct repo_paths {
722
+ git_str gitdir;
723
+ git_str workdir;
724
+ git_str gitlink;
725
+ git_str commondir;
726
+ };
727
+
728
+ #define REPO_PATHS_INIT { GIT_STR_INIT }
729
+
730
+ GIT_INLINE(void) repo_paths_dispose(struct repo_paths *paths)
731
+ {
732
+ git_str_dispose(&paths->gitdir);
733
+ git_str_dispose(&paths->workdir);
734
+ git_str_dispose(&paths->gitlink);
735
+ git_str_dispose(&paths->commondir);
736
+ }
737
+
738
+ static int find_repo_traverse(
739
+ struct repo_paths *out,
490
740
  const char *start_path,
491
- uint32_t flags,
492
- const char *ceiling_dirs)
741
+ const char *ceiling_dirs,
742
+ uint32_t flags)
493
743
  {
494
- git_buf path = GIT_BUF_INIT;
495
- git_buf repo_link = GIT_BUF_INIT;
496
- git_buf common_link = GIT_BUF_INIT;
744
+ git_str path = GIT_STR_INIT;
745
+ git_str repo_link = GIT_STR_INIT;
746
+ git_str common_link = GIT_STR_INIT;
497
747
  struct stat st;
498
748
  dev_t initial_device = 0;
499
749
  int min_iterations;
@@ -501,19 +751,23 @@ static int find_repo(
501
751
  size_t ceiling_offset = 0;
502
752
  int error;
503
753
 
504
- git_buf_clear(gitdir_path);
754
+ git_str_clear(&out->gitdir);
505
755
 
506
- error = git_path_prettify(&path, start_path, NULL);
507
- if (error < 0)
756
+ if ((error = git_fs_path_prettify(&path, start_path, NULL)) < 0)
508
757
  return error;
509
758
 
510
- /* in_dot_git toggles each loop:
759
+ /*
760
+ * In each loop we look first for a `.git` dir within the
761
+ * directory, then to see if the directory itself is a repo.
762
+ *
763
+ * In other words: if we start in /a/b/c, then we look at:
511
764
  * /a/b/c/.git, /a/b/c, /a/b/.git, /a/b, /a/.git, /a
512
- * With GIT_REPOSITORY_OPEN_BARE or GIT_REPOSITORY_OPEN_NO_DOTGIT, we
513
- * assume we started with /a/b/c.git and don't append .git the first
514
- * time through.
515
- * min_iterations indicates the number of iterations left before going
516
- * further counts as a search. */
765
+ *
766
+ * With GIT_REPOSITORY_OPEN_BARE or GIT_REPOSITORY_OPEN_NO_DOTGIT,
767
+ * we assume we started with /a/b/c.git and don't append .git the
768
+ * first time through. min_iterations indicates the number of
769
+ * iterations left before going further counts as a search.
770
+ */
517
771
  if (flags & (GIT_REPOSITORY_OPEN_BARE | GIT_REPOSITORY_OPEN_NO_DOTGIT)) {
518
772
  in_dot_git = true;
519
773
  min_iterations = 1;
@@ -525,7 +779,7 @@ static int find_repo(
525
779
  for (;;) {
526
780
  if (!(flags & GIT_REPOSITORY_OPEN_NO_DOTGIT)) {
527
781
  if (!in_dot_git) {
528
- if ((error = git_buf_joinpath(&path, path.ptr, DOT_GIT)) < 0)
782
+ if ((error = git_str_joinpath(&path, path.ptr, DOT_GIT)) < 0)
529
783
  goto out;
530
784
  }
531
785
  in_dot_git = !in_dot_git;
@@ -540,48 +794,51 @@ static int find_repo(
540
794
  break;
541
795
 
542
796
  if (S_ISDIR(st.st_mode)) {
543
- if ((error = is_valid_repository_path(&is_valid, &path, &common_link)) < 0)
797
+ if ((error = is_valid_repository_path(&is_valid, &path, &common_link, flags)) < 0)
544
798
  goto out;
545
799
 
546
800
  if (is_valid) {
547
- if ((error = git_path_to_dir(&path)) < 0 ||
548
- (error = git_buf_set(gitdir_path, path.ptr, path.size)) < 0)
801
+ if ((error = git_fs_path_to_dir(&path)) < 0 ||
802
+ (error = git_str_set(&out->gitdir, path.ptr, path.size)) < 0)
549
803
  goto out;
550
804
 
551
- if (gitlink_path)
552
- if ((error = git_buf_attach(gitlink_path, git_worktree__read_link(path.ptr, GIT_GITDIR_FILE), 0)) < 0)
553
- goto out;
554
- if (commondir_path)
555
- git_buf_swap(&common_link, commondir_path);
805
+ if ((error = git_str_attach(&out->gitlink, git_worktree__read_link(path.ptr, GIT_GITDIR_FILE), 0)) < 0)
806
+ goto out;
807
+
808
+ git_str_swap(&common_link, &out->commondir);
556
809
 
557
810
  break;
558
811
  }
559
812
  } else if (S_ISREG(st.st_mode) && git__suffixcmp(path.ptr, "/" DOT_GIT) == 0) {
560
813
  if ((error = read_gitfile(&repo_link, path.ptr)) < 0 ||
561
- (error = is_valid_repository_path(&is_valid, &repo_link, &common_link)) < 0)
814
+ (error = is_valid_repository_path(&is_valid, &repo_link, &common_link, flags)) < 0)
562
815
  goto out;
563
816
 
564
817
  if (is_valid) {
565
- git_buf_swap(gitdir_path, &repo_link);
818
+ git_str_swap(&out->gitdir, &repo_link);
819
+
820
+ if ((error = git_str_put(&out->gitlink, path.ptr, path.size)) < 0)
821
+ goto out;
566
822
 
567
- if (gitlink_path)
568
- if ((error = git_buf_put(gitlink_path, path.ptr, path.size)) < 0)
569
- goto out;
570
- if (commondir_path)
571
- git_buf_swap(&common_link, commondir_path);
823
+ git_str_swap(&common_link, &out->commondir);
572
824
  }
573
825
  break;
574
826
  }
575
827
  }
576
828
 
577
- /* Move up one directory. If we're in_dot_git, we'll search the
578
- * parent itself next. If we're !in_dot_git, we'll search .git
579
- * in the parent directory next (added at the top of the loop). */
580
- if ((error = git_path_dirname_r(&path, path.ptr)) < 0)
829
+ /*
830
+ * Move up one directory. If we're in_dot_git, we'll
831
+ * search the parent itself next. If we're !in_dot_git,
832
+ * we'll search .git in the parent directory next (added
833
+ * at the top of the loop).
834
+ */
835
+ if ((error = git_fs_path_dirname_r(&path, path.ptr)) < 0)
581
836
  goto out;
582
837
 
583
- /* Once we've checked the directory (and .git if applicable),
584
- * find the ceiling for a search. */
838
+ /*
839
+ * Once we've checked the directory (and .git if
840
+ * applicable), find the ceiling for a search.
841
+ */
585
842
  if (min_iterations && (--min_iterations == 0))
586
843
  ceiling_offset = find_ceiling_dir_offset(path.ptr, ceiling_dirs);
587
844
 
@@ -591,238 +848,242 @@ static int find_repo(
591
848
  break;
592
849
  }
593
850
 
594
- if (workdir_path && !(flags & GIT_REPOSITORY_OPEN_BARE)) {
595
- if (!git_buf_len(gitdir_path))
596
- git_buf_clear(workdir_path);
597
- else if ((error = git_path_dirname_r(workdir_path, path.ptr)) < 0 ||
598
- (error = git_path_to_dir(workdir_path)) < 0)
851
+ if (!(flags & GIT_REPOSITORY_OPEN_BARE)) {
852
+ if (!git_str_len(&out->gitdir))
853
+ git_str_clear(&out->workdir);
854
+ else if ((error = git_fs_path_dirname_r(&out->workdir, path.ptr)) < 0 ||
855
+ (error = git_fs_path_to_dir(&out->workdir)) < 0)
599
856
  goto out;
600
857
  }
601
858
 
602
- /* If we didn't find the repository, and we don't have any other error
603
- * to report, report that. */
604
- if (!git_buf_len(gitdir_path)) {
605
- git_error_set(GIT_ERROR_REPOSITORY, "could not find repository from '%s'", start_path);
859
+ /* If we didn't find the repository, and we don't have any other
860
+ * error to report, report that. */
861
+ if (!git_str_len(&out->gitdir)) {
862
+ git_error_set(GIT_ERROR_REPOSITORY, "could not find repository at '%s'", start_path);
606
863
  error = GIT_ENOTFOUND;
607
864
  goto out;
608
865
  }
609
866
 
610
867
  out:
611
- git_buf_dispose(&path);
612
- git_buf_dispose(&repo_link);
613
- git_buf_dispose(&common_link);
868
+ if (error)
869
+ repo_paths_dispose(out);
870
+
871
+ git_str_dispose(&path);
872
+ git_str_dispose(&repo_link);
873
+ git_str_dispose(&common_link);
614
874
  return error;
615
875
  }
616
876
 
617
- int git_repository_open_bare(
618
- git_repository **repo_ptr,
619
- const char *bare_path)
877
+ static int load_grafts(git_repository *repo)
620
878
  {
621
- git_buf path = GIT_BUF_INIT, common_path = GIT_BUF_INIT;
622
- git_repository *repo = NULL;
623
- bool is_valid;
879
+ git_str path = GIT_STR_INIT;
624
880
  int error;
625
881
 
626
- if ((error = git_path_prettify_dir(&path, bare_path, NULL)) < 0 ||
627
- (error = is_valid_repository_path(&is_valid, &path, &common_path)) < 0)
628
- return error;
882
+ /* refresh if they've both been opened previously */
883
+ if (repo->grafts && repo->shallow_grafts) {
884
+ if ((error = git_grafts_refresh(repo->grafts)) < 0 ||
885
+ (error = git_grafts_refresh(repo->shallow_grafts)) < 0)
886
+ return error;
887
+ }
629
888
 
630
- if (!is_valid) {
631
- git_buf_dispose(&path);
632
- git_buf_dispose(&common_path);
633
- git_error_set(GIT_ERROR_REPOSITORY, "path is not a repository: %s", bare_path);
634
- return GIT_ENOTFOUND;
889
+ /* resolve info path, which may not be found for inmemory repository */
890
+ if ((error = git_repository__item_path(&path, repo, GIT_REPOSITORY_ITEM_INFO)) < 0) {
891
+ if (error != GIT_ENOTFOUND)
892
+ return error;
893
+
894
+ /* create empty/inmemory grafts for inmemory repository */
895
+ if (!repo->grafts && (error = git_grafts_new(&repo->grafts, repo->oid_type)) < 0)
896
+ return error;
897
+
898
+ if (!repo->shallow_grafts && (error = git_grafts_new(&repo->shallow_grafts, repo->oid_type)) < 0)
899
+ return error;
900
+
901
+ return 0;
635
902
  }
636
903
 
637
- repo = repository_alloc();
638
- GIT_ERROR_CHECK_ALLOC(repo);
904
+ /* load grafts from disk */
905
+ if ((error = git_str_joinpath(&path, path.ptr, "grafts")) < 0 ||
906
+ (error = git_grafts_open_or_refresh(&repo->grafts, path.ptr, repo->oid_type)) < 0)
907
+ goto error;
639
908
 
640
- repo->gitdir = git_buf_detach(&path);
641
- GIT_ERROR_CHECK_ALLOC(repo->gitdir);
642
- repo->commondir = git_buf_detach(&common_path);
643
- GIT_ERROR_CHECK_ALLOC(repo->commondir);
909
+ git_str_clear(&path);
644
910
 
645
- /* of course we're bare! */
646
- repo->is_bare = 1;
647
- repo->is_worktree = 0;
648
- repo->workdir = NULL;
911
+ if ((error = git_str_joinpath(&path, repo->gitdir, "shallow")) < 0 ||
912
+ (error = git_grafts_open_or_refresh(&repo->shallow_grafts, path.ptr, repo->oid_type)) < 0)
913
+ goto error;
649
914
 
650
- *repo_ptr = repo;
651
- return 0;
915
+ error:
916
+ git_str_dispose(&path);
917
+ return error;
652
918
  }
653
919
 
654
- static int _git_repository_open_ext_from_env(
655
- git_repository **out,
656
- const char *start_path)
920
+ static int find_repo(
921
+ struct repo_paths *out,
922
+ const char *start_path,
923
+ const char *ceiling_dirs,
924
+ uint32_t flags)
657
925
  {
658
- git_repository *repo = NULL;
659
- git_index *index = NULL;
660
- git_odb *odb = NULL;
661
- git_buf dir_buf = GIT_BUF_INIT;
662
- git_buf ceiling_dirs_buf = GIT_BUF_INIT;
663
- git_buf across_fs_buf = GIT_BUF_INIT;
664
- git_buf index_file_buf = GIT_BUF_INIT;
665
- git_buf namespace_buf = GIT_BUF_INIT;
666
- git_buf object_dir_buf = GIT_BUF_INIT;
667
- git_buf alts_buf = GIT_BUF_INIT;
668
- git_buf work_tree_buf = GIT_BUF_INIT;
669
- git_buf common_dir_buf = GIT_BUF_INIT;
670
- const char *ceiling_dirs = NULL;
671
- unsigned flags = 0;
926
+ bool use_env = !!(flags & GIT_REPOSITORY_OPEN_FROM_ENV);
927
+ git_str gitdir_buf = GIT_STR_INIT,
928
+ ceiling_dirs_buf = GIT_STR_INIT,
929
+ across_fs_buf = GIT_STR_INIT;
672
930
  int error;
673
931
 
674
- if (!start_path) {
675
- error = git__getenv(&dir_buf, "GIT_DIR");
676
- if (error == GIT_ENOTFOUND) {
677
- git_error_clear();
678
- start_path = ".";
679
- } else if (error < 0)
680
- goto error;
681
- else {
682
- start_path = git_buf_cstr(&dir_buf);
932
+ if (use_env && !start_path) {
933
+ error = git__getenv(&gitdir_buf, "GIT_DIR");
934
+
935
+ if (!error) {
936
+ start_path = gitdir_buf.ptr;
683
937
  flags |= GIT_REPOSITORY_OPEN_NO_SEARCH;
684
938
  flags |= GIT_REPOSITORY_OPEN_NO_DOTGIT;
939
+ } else if (error == GIT_ENOTFOUND) {
940
+ start_path = ".";
941
+ } else {
942
+ goto done;
685
943
  }
686
944
  }
687
945
 
688
- error = git__getenv(&ceiling_dirs_buf, "GIT_CEILING_DIRECTORIES");
689
- if (error == GIT_ENOTFOUND)
690
- git_error_clear();
691
- else if (error < 0)
692
- goto error;
693
- else
694
- ceiling_dirs = git_buf_cstr(&ceiling_dirs_buf);
946
+ if (use_env && !ceiling_dirs) {
947
+ error = git__getenv(&ceiling_dirs_buf,
948
+ "GIT_CEILING_DIRECTORIES");
695
949
 
696
- error = git__getenv(&across_fs_buf, "GIT_DISCOVERY_ACROSS_FILESYSTEM");
697
- if (error == GIT_ENOTFOUND)
698
- git_error_clear();
699
- else if (error < 0)
700
- goto error;
701
- else {
702
- int across_fs = 0;
703
- error = git_config_parse_bool(&across_fs, git_buf_cstr(&across_fs_buf));
704
- if (error < 0)
705
- goto error;
706
- if (across_fs)
707
- flags |= GIT_REPOSITORY_OPEN_CROSS_FS;
950
+ if (!error)
951
+ ceiling_dirs = ceiling_dirs_buf.ptr;
952
+ else if (error != GIT_ENOTFOUND)
953
+ goto done;
708
954
  }
709
955
 
710
- error = git__getenv(&index_file_buf, "GIT_INDEX_FILE");
711
- if (error == GIT_ENOTFOUND)
712
- git_error_clear();
713
- else if (error < 0)
714
- goto error;
715
- else {
716
- error = git_index_open(&index, git_buf_cstr(&index_file_buf));
717
- if (error < 0)
718
- goto error;
719
- }
956
+ if (use_env) {
957
+ error = git__getenv(&across_fs_buf,
958
+ "GIT_DISCOVERY_ACROSS_FILESYSTEM");
720
959
 
721
- error = git__getenv(&namespace_buf, "GIT_NAMESPACE");
722
- if (error == GIT_ENOTFOUND)
723
- git_error_clear();
724
- else if (error < 0)
725
- goto error;
960
+ if (!error) {
961
+ int across_fs = 0;
726
962
 
727
- error = git__getenv(&object_dir_buf, "GIT_OBJECT_DIRECTORY");
728
- if (error == GIT_ENOTFOUND)
729
- git_error_clear();
730
- else if (error < 0)
731
- goto error;
732
- else {
733
- error = git_odb_open(&odb, git_buf_cstr(&object_dir_buf));
734
- if (error < 0)
735
- goto error;
736
- }
963
+ if ((error = git_config_parse_bool(&across_fs,
964
+ git_str_cstr(&across_fs_buf))) < 0)
965
+ goto done;
737
966
 
738
- error = git__getenv(&work_tree_buf, "GIT_WORK_TREE");
739
- if (error == GIT_ENOTFOUND)
740
- git_error_clear();
741
- else if (error < 0)
742
- goto error;
743
- else {
744
- git_error_set(GIT_ERROR_INVALID, "GIT_WORK_TREE unimplemented");
745
- error = GIT_ERROR;
746
- goto error;
967
+ if (across_fs)
968
+ flags |= GIT_REPOSITORY_OPEN_CROSS_FS;
969
+ } else if (error != GIT_ENOTFOUND) {
970
+ goto done;
971
+ }
747
972
  }
748
973
 
749
- error = git__getenv(&work_tree_buf, "GIT_COMMON_DIR");
750
- if (error == GIT_ENOTFOUND)
751
- git_error_clear();
752
- else if (error < 0)
753
- goto error;
754
- else {
755
- git_error_set(GIT_ERROR_INVALID, "GIT_COMMON_DIR unimplemented");
756
- error = GIT_ERROR;
757
- goto error;
758
- }
974
+ error = find_repo_traverse(out, start_path, ceiling_dirs, flags);
759
975
 
760
- error = git_repository_open_ext(&repo, start_path, flags, ceiling_dirs);
761
- if (error < 0)
762
- goto error;
976
+ done:
977
+ git_str_dispose(&gitdir_buf);
978
+ git_str_dispose(&ceiling_dirs_buf);
979
+ git_str_dispose(&across_fs_buf);
763
980
 
764
- if (odb)
765
- git_repository_set_odb(repo, odb);
981
+ return error;
982
+ }
766
983
 
767
- error = git__getenv(&alts_buf, "GIT_ALTERNATE_OBJECT_DIRECTORIES");
768
- if (error == GIT_ENOTFOUND) {
769
- git_error_clear();
770
- error = 0;
771
- } else if (error < 0)
772
- goto error;
773
- else {
774
- const char *end;
775
- char *alt, *sep;
776
- if (!odb) {
777
- error = git_repository_odb(&odb, repo);
778
- if (error < 0)
779
- goto error;
780
- }
984
+ static int obtain_config_and_set_oid_type(
985
+ git_config **config_ptr,
986
+ git_repository *repo)
987
+ {
988
+ int error;
989
+ git_config *config = NULL;
990
+ int version = 0;
781
991
 
782
- end = git_buf_cstr(&alts_buf) + git_buf_len(&alts_buf);
783
- for (sep = alt = alts_buf.ptr; sep != end; alt = sep+1) {
784
- for (sep = alt; *sep && *sep != GIT_PATH_LIST_SEPARATOR; sep++)
785
- ;
786
- if (*sep)
787
- *sep = '\0';
788
- error = git_odb_add_disk_alternate(odb, alt);
789
- if (error < 0)
790
- goto error;
791
- }
792
- }
992
+ /*
993
+ * We'd like to have the config, but git doesn't particularly
994
+ * care if it's not there, so we need to deal with that.
995
+ */
793
996
 
794
- if (git_buf_len(&namespace_buf)) {
795
- error = git_repository_set_namespace(repo, git_buf_cstr(&namespace_buf));
796
- if (error < 0)
797
- goto error;
997
+ error = git_repository_config_snapshot(&config, repo);
998
+ if (error < 0 && error != GIT_ENOTFOUND)
999
+ goto out;
1000
+
1001
+ if (config &&
1002
+ (error = check_repositoryformatversion(&version, config)) < 0)
1003
+ goto out;
1004
+
1005
+ if ((error = check_extensions(config, version)) < 0)
1006
+ goto out;
1007
+
1008
+ if (version > 0) {
1009
+ if ((error = load_objectformat(repo, config)) < 0)
1010
+ goto out;
1011
+ } else {
1012
+ repo->oid_type = GIT_OID_DEFAULT;
798
1013
  }
799
1014
 
800
- git_repository_set_index(repo, index);
1015
+ out:
1016
+ *config_ptr = config;
1017
+
1018
+ return error;
1019
+ }
801
1020
 
802
- if (out) {
803
- *out = repo;
804
- goto success;
1021
+ int git_repository_open_bare(
1022
+ git_repository **repo_ptr,
1023
+ const char *bare_path)
1024
+ {
1025
+ git_str path = GIT_STR_INIT, common_path = GIT_STR_INIT;
1026
+ git_repository *repo = NULL;
1027
+ bool is_valid;
1028
+ int error;
1029
+ git_config *config;
1030
+
1031
+ if ((error = git_fs_path_prettify_dir(&path, bare_path, NULL)) < 0 ||
1032
+ (error = is_valid_repository_path(&is_valid, &path, &common_path, 0)) < 0)
1033
+ return error;
1034
+
1035
+ if (!is_valid) {
1036
+ git_str_dispose(&path);
1037
+ git_str_dispose(&common_path);
1038
+ git_error_set(GIT_ERROR_REPOSITORY, "path is not a repository: %s", bare_path);
1039
+ return GIT_ENOTFOUND;
805
1040
  }
806
- error:
807
- git_repository_free(repo);
808
- success:
809
- git_odb_free(odb);
810
- git_index_free(index);
811
- git_buf_dispose(&common_dir_buf);
812
- git_buf_dispose(&work_tree_buf);
813
- git_buf_dispose(&alts_buf);
814
- git_buf_dispose(&object_dir_buf);
815
- git_buf_dispose(&namespace_buf);
816
- git_buf_dispose(&index_file_buf);
817
- git_buf_dispose(&across_fs_buf);
818
- git_buf_dispose(&ceiling_dirs_buf);
819
- git_buf_dispose(&dir_buf);
1041
+
1042
+ repo = repository_alloc();
1043
+ GIT_ERROR_CHECK_ALLOC(repo);
1044
+
1045
+ repo->gitdir = git_str_detach(&path);
1046
+ GIT_ERROR_CHECK_ALLOC(repo->gitdir);
1047
+ repo->commondir = git_str_detach(&common_path);
1048
+ GIT_ERROR_CHECK_ALLOC(repo->commondir);
1049
+
1050
+ /* of course we're bare! */
1051
+ repo->is_bare = 1;
1052
+ repo->is_worktree = 0;
1053
+ repo->workdir = NULL;
1054
+
1055
+ if ((error = obtain_config_and_set_oid_type(&config, repo)) < 0)
1056
+ goto cleanup;
1057
+
1058
+ *repo_ptr = repo;
1059
+
1060
+ cleanup:
1061
+ git_config_free(config);
1062
+
820
1063
  return error;
821
1064
  }
822
1065
 
1066
+ static int repo_load_namespace(git_repository *repo)
1067
+ {
1068
+ git_str namespace_buf = GIT_STR_INIT;
1069
+ int error;
1070
+
1071
+ if (!repo->use_env)
1072
+ return 0;
1073
+
1074
+ error = git__getenv(&namespace_buf, "GIT_NAMESPACE");
1075
+
1076
+ if (error == 0)
1077
+ repo->namespace = git_str_detach(&namespace_buf);
1078
+ else if (error != GIT_ENOTFOUND)
1079
+ return error;
1080
+
1081
+ return 0;
1082
+ }
1083
+
823
1084
  static int repo_is_worktree(unsigned *out, const git_repository *repo)
824
1085
  {
825
- git_buf gitdir_link = GIT_BUF_INIT;
1086
+ git_str gitdir_link = GIT_STR_INIT;
826
1087
  int error;
827
1088
 
828
1089
  /* Worktrees cannot have the same commondir and gitdir */
@@ -832,14 +1093,14 @@ static int repo_is_worktree(unsigned *out, const git_repository *repo)
832
1093
  return 0;
833
1094
  }
834
1095
 
835
- if ((error = git_buf_joinpath(&gitdir_link, repo->gitdir, "gitdir")) < 0)
1096
+ if ((error = git_str_joinpath(&gitdir_link, repo->gitdir, "gitdir")) < 0)
836
1097
  return -1;
837
1098
 
838
1099
  /* A 'gitdir' file inside a git directory is currently
839
1100
  * only used when the repository is a working tree. */
840
- *out = !!git_path_exists(gitdir_link.ptr);
1101
+ *out = !!git_fs_path_exists(gitdir_link.ptr);
841
1102
 
842
- git_buf_dispose(&gitdir_link);
1103
+ git_str_dispose(&gitdir_link);
843
1104
  return error;
844
1105
  }
845
1106
 
@@ -849,22 +1110,16 @@ int git_repository_open_ext(
849
1110
  unsigned int flags,
850
1111
  const char *ceiling_dirs)
851
1112
  {
852
- int error;
853
- unsigned is_worktree;
854
- git_buf gitdir = GIT_BUF_INIT, workdir = GIT_BUF_INIT,
855
- gitlink = GIT_BUF_INIT, commondir = GIT_BUF_INIT;
1113
+ struct repo_paths paths = { GIT_STR_INIT };
856
1114
  git_repository *repo = NULL;
857
1115
  git_config *config = NULL;
858
- int version = 0;
859
-
860
- if (flags & GIT_REPOSITORY_OPEN_FROM_ENV)
861
- return _git_repository_open_ext_from_env(repo_ptr, start_path);
1116
+ unsigned is_worktree;
1117
+ int error;
862
1118
 
863
1119
  if (repo_ptr)
864
1120
  *repo_ptr = NULL;
865
1121
 
866
- error = find_repo(
867
- &gitdir, &workdir, &gitlink, &commondir, start_path, flags, ceiling_dirs);
1122
+ error = find_repo(&paths, start_path, ceiling_dirs, flags);
868
1123
 
869
1124
  if (error < 0 || !repo_ptr)
870
1125
  goto cleanup;
@@ -872,52 +1127,54 @@ int git_repository_open_ext(
872
1127
  repo = repository_alloc();
873
1128
  GIT_ERROR_CHECK_ALLOC(repo);
874
1129
 
875
- repo->gitdir = git_buf_detach(&gitdir);
1130
+ repo->use_env = !!(flags & GIT_REPOSITORY_OPEN_FROM_ENV);
1131
+
1132
+ repo->gitdir = git_str_detach(&paths.gitdir);
876
1133
  GIT_ERROR_CHECK_ALLOC(repo->gitdir);
877
1134
 
878
- if (gitlink.size) {
879
- repo->gitlink = git_buf_detach(&gitlink);
1135
+ if (paths.gitlink.size) {
1136
+ repo->gitlink = git_str_detach(&paths.gitlink);
880
1137
  GIT_ERROR_CHECK_ALLOC(repo->gitlink);
881
1138
  }
882
- if (commondir.size) {
883
- repo->commondir = git_buf_detach(&commondir);
1139
+ if (paths.commondir.size) {
1140
+ repo->commondir = git_str_detach(&paths.commondir);
884
1141
  GIT_ERROR_CHECK_ALLOC(repo->commondir);
885
1142
  }
886
1143
 
887
1144
  if ((error = repo_is_worktree(&is_worktree, repo)) < 0)
888
1145
  goto cleanup;
889
- repo->is_worktree = is_worktree;
890
1146
 
891
- /*
892
- * We'd like to have the config, but git doesn't particularly
893
- * care if it's not there, so we need to deal with that.
894
- */
895
-
896
- error = git_repository_config_snapshot(&config, repo);
897
- if (error < 0 && error != GIT_ENOTFOUND)
898
- goto cleanup;
1147
+ repo->is_worktree = is_worktree;
899
1148
 
900
- if (config && (error = check_repositoryformatversion(&version, config)) < 0)
1149
+ error = obtain_config_and_set_oid_type(&config, repo);
1150
+ if (error < 0)
901
1151
  goto cleanup;
902
1152
 
903
- if ((error = check_extensions(config, version)) < 0)
1153
+ if ((error = load_grafts(repo)) < 0)
904
1154
  goto cleanup;
905
1155
 
906
- if ((flags & GIT_REPOSITORY_OPEN_BARE) != 0)
1156
+ if ((flags & GIT_REPOSITORY_OPEN_BARE) != 0) {
907
1157
  repo->is_bare = 1;
908
- else {
909
-
1158
+ } else {
910
1159
  if (config &&
911
1160
  ((error = load_config_data(repo, config)) < 0 ||
912
- (error = load_workdir(repo, config, &workdir)) < 0))
1161
+ (error = load_workdir(repo, config, &paths.workdir)) < 0))
913
1162
  goto cleanup;
914
1163
  }
915
1164
 
1165
+ if ((error = repo_load_namespace(repo)) < 0)
1166
+ goto cleanup;
1167
+
1168
+ /*
1169
+ * Ensure that the git directory and worktree are
1170
+ * owned by the current user.
1171
+ */
1172
+ if (git_repository__validate_ownership &&
1173
+ (error = validate_ownership(repo)) < 0)
1174
+ goto cleanup;
1175
+
916
1176
  cleanup:
917
- git_buf_dispose(&gitdir);
918
- git_buf_dispose(&workdir);
919
- git_buf_dispose(&gitlink);
920
- git_buf_dispose(&commondir);
1177
+ repo_paths_dispose(&paths);
921
1178
  git_config_free(config);
922
1179
 
923
1180
  if (error < 0)
@@ -936,7 +1193,7 @@ int git_repository_open(git_repository **repo_out, const char *path)
936
1193
 
937
1194
  int git_repository_open_from_worktree(git_repository **repo_out, git_worktree *wt)
938
1195
  {
939
- git_buf path = GIT_BUF_INIT;
1196
+ git_str path = GIT_STR_INIT;
940
1197
  git_repository *repo = NULL;
941
1198
  size_t len;
942
1199
  int err;
@@ -952,7 +1209,7 @@ int git_repository_open_from_worktree(git_repository **repo_out, git_worktree *w
952
1209
  goto out;
953
1210
  }
954
1211
 
955
- if ((err = git_buf_set(&path, wt->gitlink_path, len - 4)) < 0)
1212
+ if ((err = git_str_set(&path, wt->gitlink_path, len - 4)) < 0)
956
1213
  goto out;
957
1214
 
958
1215
  if ((err = git_repository_open(&repo, path.ptr)) < 0)
@@ -961,20 +1218,23 @@ int git_repository_open_from_worktree(git_repository **repo_out, git_worktree *w
961
1218
  *repo_out = repo;
962
1219
 
963
1220
  out:
964
- git_buf_dispose(&path);
1221
+ git_str_dispose(&path);
965
1222
 
966
1223
  return err;
967
1224
  }
968
1225
 
969
- int git_repository_wrap_odb(git_repository **repo_out, git_odb *odb)
1226
+ int git_repository_wrap_odb(git_repository **out, git_odb *odb)
970
1227
  {
971
1228
  git_repository *repo;
972
1229
 
973
1230
  repo = repository_alloc();
974
1231
  GIT_ERROR_CHECK_ALLOC(repo);
975
1232
 
1233
+ GIT_ASSERT(git_oid_type_is_valid(odb->options.oid_type));
1234
+ repo->oid_type = odb->options.oid_type;
1235
+
976
1236
  git_repository_set_odb(repo, odb);
977
- *repo_out = repo;
1237
+ *out = repo;
978
1238
 
979
1239
  return 0;
980
1240
  }
@@ -985,15 +1245,35 @@ int git_repository_discover(
985
1245
  int across_fs,
986
1246
  const char *ceiling_dirs)
987
1247
  {
1248
+ struct repo_paths paths = { GIT_STR_INIT };
988
1249
  uint32_t flags = across_fs ? GIT_REPOSITORY_OPEN_CROSS_FS : 0;
989
1250
  int error;
990
1251
 
991
1252
  GIT_ASSERT_ARG(start_path);
992
1253
 
993
- if ((error = git_buf_sanitize(out)) < 0)
1254
+ if ((error = find_repo(&paths, start_path, ceiling_dirs, flags)) == 0)
1255
+ error = git_buf_fromstr(out, &paths.gitdir);
1256
+
1257
+ repo_paths_dispose(&paths);
1258
+ return error;
1259
+ }
1260
+
1261
+ static int has_config_worktree(bool *out, git_config *cfg)
1262
+ {
1263
+ int worktreeconfig = 0, error;
1264
+
1265
+ *out = false;
1266
+
1267
+ error = git_config_get_bool(&worktreeconfig, cfg, "extensions.worktreeconfig");
1268
+
1269
+ if (error == 0)
1270
+ *out = worktreeconfig;
1271
+ else if (error == GIT_ENOTFOUND)
1272
+ *out = false;
1273
+ else
994
1274
  return error;
995
1275
 
996
- return find_repo(out, NULL, NULL, NULL, start_path, flags, ceiling_dirs);
1276
+ return 0;
997
1277
  }
998
1278
 
999
1279
  static int load_config(
@@ -1004,9 +1284,11 @@ static int load_config(
1004
1284
  const char *system_config_path,
1005
1285
  const char *programdata_path)
1006
1286
  {
1007
- int error;
1008
- git_buf config_path = GIT_BUF_INIT;
1287
+ git_str config_path = GIT_STR_INIT;
1009
1288
  git_config *cfg = NULL;
1289
+ git_config_level_t write_order;
1290
+ bool has_worktree;
1291
+ int error;
1010
1292
 
1011
1293
  GIT_ASSERT_ARG(out);
1012
1294
 
@@ -1014,13 +1296,21 @@ static int load_config(
1014
1296
  return error;
1015
1297
 
1016
1298
  if (repo) {
1017
- if ((error = git_repository_item_path(&config_path, repo, GIT_REPOSITORY_ITEM_CONFIG)) == 0)
1299
+ if ((error = git_repository__item_path(&config_path, repo, GIT_REPOSITORY_ITEM_CONFIG)) == 0)
1018
1300
  error = git_config_add_file_ondisk(cfg, config_path.ptr, GIT_CONFIG_LEVEL_LOCAL, repo, 0);
1019
1301
 
1020
1302
  if (error && error != GIT_ENOTFOUND)
1021
1303
  goto on_error;
1022
1304
 
1023
- git_buf_dispose(&config_path);
1305
+ if ((error = has_config_worktree(&has_worktree, cfg)) == 0 &&
1306
+ has_worktree &&
1307
+ (error = git_repository__item_path(&config_path, repo, GIT_REPOSITORY_ITEM_WORKTREE_CONFIG)) == 0)
1308
+ error = git_config_add_file_ondisk(cfg, config_path.ptr, GIT_CONFIG_LEVEL_WORKTREE, repo, 0);
1309
+
1310
+ if (error && error != GIT_ENOTFOUND)
1311
+ goto on_error;
1312
+
1313
+ git_str_dispose(&config_path);
1024
1314
  }
1025
1315
 
1026
1316
  if (global_config_path != NULL &&
@@ -1049,19 +1339,65 @@ static int load_config(
1049
1339
 
1050
1340
  git_error_clear(); /* clear any lingering ENOTFOUND errors */
1051
1341
 
1342
+ write_order = GIT_CONFIG_LEVEL_LOCAL;
1343
+
1344
+ if ((error = git_config_set_writeorder(cfg, &write_order, 1)) < 0)
1345
+ goto on_error;
1346
+
1052
1347
  *out = cfg;
1053
1348
  return 0;
1054
1349
 
1055
1350
  on_error:
1056
- git_buf_dispose(&config_path);
1351
+ git_str_dispose(&config_path);
1057
1352
  git_config_free(cfg);
1058
1353
  *out = NULL;
1059
1354
  return error;
1060
1355
  }
1061
1356
 
1062
- static const char *path_unless_empty(git_buf *buf)
1357
+ static const char *path_unless_empty(git_str *buf)
1358
+ {
1359
+ return git_str_len(buf) > 0 ? git_str_cstr(buf) : NULL;
1360
+ }
1361
+
1362
+ GIT_INLINE(int) config_path_system(git_str *out, bool use_env)
1363
+ {
1364
+ if (use_env) {
1365
+ git_str no_system_buf = GIT_STR_INIT;
1366
+ int no_system = 0;
1367
+ int error;
1368
+
1369
+ error = git__getenv(&no_system_buf, "GIT_CONFIG_NOSYSTEM");
1370
+
1371
+ if (error && error != GIT_ENOTFOUND)
1372
+ return error;
1373
+
1374
+ error = git_config_parse_bool(&no_system, no_system_buf.ptr);
1375
+ git_str_dispose(&no_system_buf);
1376
+
1377
+ if (no_system)
1378
+ return 0;
1379
+
1380
+ error = git__getenv(out, "GIT_CONFIG_SYSTEM");
1381
+
1382
+ if (error == 0 || error != GIT_ENOTFOUND)
1383
+ return 0;
1384
+ }
1385
+
1386
+ git_config__find_system(out);
1387
+ return 0;
1388
+ }
1389
+
1390
+ GIT_INLINE(int) config_path_global(git_str *out, bool use_env)
1063
1391
  {
1064
- return git_buf_len(buf) > 0 ? git_buf_cstr(buf) : NULL;
1392
+ if (use_env) {
1393
+ int error = git__getenv(out, "GIT_CONFIG_GLOBAL");
1394
+
1395
+ if (error == 0 || error != GIT_ENOTFOUND)
1396
+ return 0;
1397
+ }
1398
+
1399
+ git_config__find_global(out);
1400
+ return 0;
1065
1401
  }
1066
1402
 
1067
1403
  int git_repository_config__weakptr(git_config **out, git_repository *repo)
@@ -1069,27 +1405,35 @@ int git_repository_config__weakptr(git_config **out, git_repository *repo)
1069
1405
  int error = 0;
1070
1406
 
1071
1407
  if (repo->_config == NULL) {
1072
- git_buf global_buf = GIT_BUF_INIT;
1073
- git_buf xdg_buf = GIT_BUF_INIT;
1074
- git_buf system_buf = GIT_BUF_INIT;
1075
- git_buf programdata_buf = GIT_BUF_INIT;
1408
+ git_str system_buf = GIT_STR_INIT;
1409
+ git_str global_buf = GIT_STR_INIT;
1410
+ git_str xdg_buf = GIT_STR_INIT;
1411
+ git_str programdata_buf = GIT_STR_INIT;
1412
+ bool use_env = repo->use_env;
1076
1413
  git_config *config;
1077
1414
 
1078
- git_config_find_global(&global_buf);
1079
- git_config_find_xdg(&xdg_buf);
1080
- git_config_find_system(&system_buf);
1081
- git_config_find_programdata(&programdata_buf);
1082
-
1083
- /* If there is no global file, open a backend for it anyway */
1084
- if (git_buf_len(&global_buf) == 0)
1085
- git_config__global_location(&global_buf);
1086
-
1087
- error = load_config(
1088
- &config, repo,
1089
- path_unless_empty(&global_buf),
1090
- path_unless_empty(&xdg_buf),
1091
- path_unless_empty(&system_buf),
1092
- path_unless_empty(&programdata_buf));
1415
+ if (!(error = config_path_system(&system_buf, use_env)) &&
1416
+ !(error = config_path_global(&global_buf, use_env))) {
1417
+ git_config__find_xdg(&xdg_buf);
1418
+ git_config__find_programdata(&programdata_buf);
1419
+ }
1420
+
1421
+ if (!error) {
1422
+ /*
1423
+ * If there is no global file, open a backend
1424
+ * for it anyway.
1425
+ */
1426
+ if (git_str_len(&global_buf) == 0)
1427
+ git_config__global_location(&global_buf);
1428
+
1429
+ error = load_config(
1430
+ &config, repo,
1431
+ path_unless_empty(&global_buf),
1432
+ path_unless_empty(&xdg_buf),
1433
+ path_unless_empty(&system_buf),
1434
+ path_unless_empty(&programdata_buf));
1435
+ }
1436
+
1093
1437
  if (!error) {
1094
1438
  GIT_REFCOUNT_OWN(config, repo);
1095
1439
 
@@ -1099,10 +1443,10 @@ int git_repository_config__weakptr(git_config **out, git_repository *repo)
1099
1443
  }
1100
1444
  }
1101
1445
 
1102
- git_buf_dispose(&global_buf);
1103
- git_buf_dispose(&xdg_buf);
1104
- git_buf_dispose(&system_buf);
1105
- git_buf_dispose(&programdata_buf);
1446
+ git_str_dispose(&global_buf);
1447
+ git_str_dispose(&xdg_buf);
1448
+ git_str_dispose(&system_buf);
1449
+ git_str_dispose(&programdata_buf);
1106
1450
  }
1107
1451
 
1108
1452
  *out = repo->_config;
@@ -1118,23 +1462,73 @@ int git_repository_config(git_config **out, git_repository *repo)
1118
1462
  return 0;
1119
1463
  }
1120
1464
 
1121
- int git_repository_config_snapshot(git_config **out, git_repository *repo)
1465
+ int git_repository_config_snapshot(git_config **out, git_repository *repo)
1466
+ {
1467
+ int error;
1468
+ git_config *weak;
1469
+
1470
+ if ((error = git_repository_config__weakptr(&weak, repo)) < 0)
1471
+ return error;
1472
+
1473
+ return git_config_snapshot(out, weak);
1474
+ }
1475
+
1476
+ int git_repository_set_config(git_repository *repo, git_config *config)
1477
+ {
1478
+ GIT_ASSERT_ARG(repo);
1479
+ GIT_ASSERT_ARG(config);
1480
+
1481
+ set_config(repo, config);
1482
+ return 0;
1483
+ }
1484
+
1485
+ static int repository_odb_path(git_str *out, git_repository *repo)
1486
+ {
1487
+ int error = GIT_ENOTFOUND;
1488
+
1489
+ if (repo->use_env)
1490
+ error = git__getenv(out, "GIT_OBJECT_DIRECTORY");
1491
+
1492
+ if (error == GIT_ENOTFOUND)
1493
+ error = git_repository__item_path(out, repo,
1494
+ GIT_REPOSITORY_ITEM_OBJECTS);
1495
+
1496
+ return error;
1497
+ }
1498
+
1499
+ static int repository_odb_alternates(
1500
+ git_odb *odb,
1501
+ git_repository *repo)
1122
1502
  {
1503
+ git_str alternates = GIT_STR_INIT;
1504
+ char *sep, *alt;
1123
1505
  int error;
1124
- git_config *weak;
1125
1506
 
1126
- if ((error = git_repository_config__weakptr(&weak, repo)) < 0)
1127
- return error;
1507
+ if (!repo->use_env)
1508
+ return 0;
1128
1509
 
1129
- return git_config_snapshot(out, weak);
1130
- }
1510
+ error = git__getenv(&alternates, "GIT_ALTERNATE_OBJECT_DIRECTORIES");
1131
1511
 
1132
- int git_repository_set_config(git_repository *repo, git_config *config)
1133
- {
1134
- GIT_ASSERT_ARG(repo);
1135
- GIT_ASSERT_ARG(config);
1512
+ if (error != 0)
1513
+ return (error == GIT_ENOTFOUND) ? 0 : error;
1136
1514
 
1137
- set_config(repo, config);
1515
+ alt = alternates.ptr;
1516
+
1517
+ while (*alt) {
1518
+ sep = strchr(alt, GIT_PATH_LIST_SEPARATOR);
1519
+
1520
+ if (sep)
1521
+ *sep = '\0';
1522
+
1523
+ error = git_odb_add_disk_alternate(odb, alt);
1524
+
1525
+ if (sep)
1526
+ alt = sep + 1;
1527
+ else
1528
+ break;
1529
+ }
1530
+
1531
+ git_str_dispose(&alternates);
1138
1532
  return 0;
1139
1533
  }
1140
1534
 
@@ -1147,12 +1541,15 @@ int git_repository_odb__weakptr(git_odb **out, git_repository *repo)
1147
1541
 
1148
1542
  *out = git_atomic_load(repo->_odb);
1149
1543
  if (*out == NULL) {
1150
- git_buf odb_path = GIT_BUF_INIT;
1544
+ git_str odb_path = GIT_STR_INIT;
1545
+ git_odb_options odb_opts = GIT_ODB_OPTIONS_INIT;
1151
1546
  git_odb *odb;
1152
1547
 
1153
- if ((error = git_repository_item_path(&odb_path, repo,
1154
- GIT_REPOSITORY_ITEM_OBJECTS)) < 0 ||
1155
- (error = git_odb_new(&odb)) < 0)
1548
+ odb_opts.oid_type = repo->oid_type;
1549
+
1550
+ if ((error = repository_odb_path(&odb_path, repo)) < 0 ||
1551
+ (error = git_odb__new(&odb, &odb_opts)) < 0 ||
1552
+ (error = repository_odb_alternates(odb, repo)) < 0)
1156
1553
  return error;
1157
1554
 
1158
1555
  GIT_REFCOUNT_OWN(odb, repo);
@@ -1168,7 +1565,7 @@ int git_repository_odb__weakptr(git_odb **out, git_repository *repo)
1168
1565
  git_odb_free(odb);
1169
1566
  }
1170
1567
 
1171
- git_buf_dispose(&odb_path);
1568
+ git_str_dispose(&odb_path);
1172
1569
  *out = git_atomic_load(repo->_odb);
1173
1570
  }
1174
1571
 
@@ -1236,6 +1633,20 @@ int git_repository_set_refdb(git_repository *repo, git_refdb *refdb)
1236
1633
  return 0;
1237
1634
  }
1238
1635
 
1636
+ static int repository_index_path(git_str *out, git_repository *repo)
1637
+ {
1638
+ int error = GIT_ENOTFOUND;
1639
+
1640
+ if (repo->use_env)
1641
+ error = git__getenv(out, "GIT_INDEX_FILE");
1642
+
1643
+ if (error == GIT_ENOTFOUND)
1644
+ error = git_repository__item_path(out, repo,
1645
+ GIT_REPOSITORY_ITEM_INDEX);
1646
+
1647
+ return error;
1648
+ }
1649
+
1239
1650
  int git_repository_index__weakptr(git_index **out, git_repository *repo)
1240
1651
  {
1241
1652
  int error = 0;
@@ -1244,13 +1655,14 @@ int git_repository_index__weakptr(git_index **out, git_repository *repo)
1244
1655
  GIT_ASSERT_ARG(repo);
1245
1656
 
1246
1657
  if (repo->_index == NULL) {
1247
- git_buf index_path = GIT_BUF_INIT;
1658
+ git_str index_path = GIT_STR_INIT;
1248
1659
  git_index *index;
1249
1660
 
1250
- if ((error = git_buf_joinpath(&index_path, repo->gitdir, GIT_INDEX_FILE)) < 0)
1661
+ if ((error = repository_index_path(&index_path, repo)) < 0)
1251
1662
  return error;
1252
1663
 
1253
- error = git_index_open(&index, index_path.ptr);
1664
+ error = git_index__open(&index, index_path.ptr, repo->oid_type);
1665
+
1254
1666
  if (!error) {
1255
1667
  GIT_REFCOUNT_OWN(index, repo);
1256
1668
 
@@ -1263,7 +1675,7 @@ int git_repository_index__weakptr(git_index **out, git_repository *repo)
1263
1675
  GIT_INDEX_CAPABILITY_FROM_OWNER);
1264
1676
  }
1265
1677
 
1266
- git_buf_dispose(&index_path);
1678
+ git_str_dispose(&index_path);
1267
1679
  }
1268
1680
 
1269
1681
  *out = repo->_index;
@@ -1286,6 +1698,22 @@ int git_repository_set_index(git_repository *repo, git_index *index)
1286
1698
  return 0;
1287
1699
  }
1288
1700
 
1701
+ int git_repository_grafts__weakptr(git_grafts **out, git_repository *repo)
1702
+ {
1703
+ GIT_ASSERT_ARG(out && repo);
1704
+ GIT_ASSERT(repo->grafts);
1705
+ *out = repo->grafts;
1706
+ return 0;
1707
+ }
1708
+
1709
+ int git_repository_shallow_grafts__weakptr(git_grafts **out, git_repository *repo)
1710
+ {
1711
+ GIT_ASSERT_ARG(out && repo);
1712
+ GIT_ASSERT(repo->shallow_grafts);
1713
+ *out = repo->shallow_grafts;
1714
+ return 0;
1715
+ }
1716
+
1289
1717
  int git_repository_set_namespace(git_repository *repo, const char *namespace)
1290
1718
  {
1291
1719
  git__free(repo->namespace);
@@ -1311,7 +1739,7 @@ static int reserved_names_add8dot3(git_repository *repo, const char *path)
1311
1739
  const char *def_dot_git = DOT_GIT;
1312
1740
  size_t name_len, def_len = CONST_STRLEN(GIT_DIR_SHORTNAME);
1313
1741
  size_t def_dot_git_len = CONST_STRLEN(DOT_GIT);
1314
- git_buf *buf;
1742
+ git_str *buf;
1315
1743
 
1316
1744
  if (!name)
1317
1745
  return 0;
@@ -1327,17 +1755,17 @@ static int reserved_names_add8dot3(git_repository *repo, const char *path)
1327
1755
  if ((buf = git_array_alloc(repo->reserved_names)) == NULL)
1328
1756
  return -1;
1329
1757
 
1330
- git_buf_attach(buf, name, name_len);
1758
+ git_str_attach(buf, name, name_len);
1331
1759
  return true;
1332
1760
  }
1333
1761
 
1334
1762
  bool git_repository__reserved_names(
1335
- git_buf **out, size_t *outlen, git_repository *repo, bool include_ntfs)
1763
+ git_str **out, size_t *outlen, git_repository *repo, bool include_ntfs)
1336
1764
  {
1337
1765
  GIT_UNUSED(include_ntfs);
1338
1766
 
1339
1767
  if (repo->reserved_names.size == 0) {
1340
- git_buf *buf;
1768
+ git_str *buf;
1341
1769
  size_t i;
1342
1770
 
1343
1771
  /* Add the static defaults */
@@ -1389,7 +1817,7 @@ on_error:
1389
1817
  }
1390
1818
  #else
1391
1819
  bool git_repository__reserved_names(
1392
- git_buf **out, size_t *outlen, git_repository *repo, bool include_ntfs)
1820
+ git_str **out, size_t *outlen, git_repository *repo, bool include_ntfs)
1393
1821
  {
1394
1822
  GIT_UNUSED(repo);
1395
1823
 
@@ -1410,6 +1838,7 @@ static int check_repositoryformatversion(int *version, git_config *config)
1410
1838
  int error;
1411
1839
 
1412
1840
  error = git_config_get_int32(version, config, "core.repositoryformatversion");
1841
+
1413
1842
  /* git ignores this if the config variable isn't there */
1414
1843
  if (error == GIT_ENOTFOUND)
1415
1844
  return 0;
@@ -1417,10 +1846,15 @@ static int check_repositoryformatversion(int *version, git_config *config)
1417
1846
  if (error < 0)
1418
1847
  return -1;
1419
1848
 
1420
- if (GIT_REPO_MAX_VERSION < *version) {
1849
+ if (*version < 0) {
1850
+ git_error_set(GIT_ERROR_REPOSITORY,
1851
+ "invalid repository version %d", *version);
1852
+ }
1853
+
1854
+ if (GIT_REPO_VERSION_MAX < *version) {
1421
1855
  git_error_set(GIT_ERROR_REPOSITORY,
1422
1856
  "unsupported repository version %d; only versions up to %d are supported",
1423
- *version, GIT_REPO_MAX_VERSION);
1857
+ *version, GIT_REPO_VERSION_MAX);
1424
1858
  return -1;
1425
1859
  }
1426
1860
 
@@ -1428,14 +1862,17 @@ static int check_repositoryformatversion(int *version, git_config *config)
1428
1862
  }
1429
1863
 
1430
1864
  static const char *builtin_extensions[] = {
1431
- "noop"
1865
+ "noop",
1866
+ "objectformat",
1867
+ "worktreeconfig",
1868
+ "preciousobjects"
1432
1869
  };
1433
1870
 
1434
- static git_vector user_extensions = GIT_VECTOR_INIT;
1871
+ static git_vector user_extensions = { 0, git__strcmp_cb };
1435
1872
 
1436
1873
  static int check_valid_extension(const git_config_entry *entry, void *payload)
1437
1874
  {
1438
- git_buf cfg = GIT_BUF_INIT;
1875
+ git_str cfg = GIT_STR_INIT;
1439
1876
  bool reject;
1440
1877
  const char *extension;
1441
1878
  size_t i;
@@ -1444,7 +1881,7 @@ static int check_valid_extension(const git_config_entry *entry, void *payload)
1444
1881
  GIT_UNUSED(payload);
1445
1882
 
1446
1883
  git_vector_foreach (&user_extensions, i, extension) {
1447
- git_buf_clear(&cfg);
1884
+ git_str_clear(&cfg);
1448
1885
 
1449
1886
  /*
1450
1887
  * Users can specify that they don't want to support an
@@ -1453,7 +1890,7 @@ static int check_valid_extension(const git_config_entry *entry, void *payload)
1453
1890
  if ((reject = (extension[0] == '!')) == true)
1454
1891
  extension = &extension[1];
1455
1892
 
1456
- if ((error = git_buf_printf(&cfg, "extensions.%s", extension)) < 0)
1893
+ if ((error = git_str_printf(&cfg, "extensions.%s", extension)) < 0)
1457
1894
  goto done;
1458
1895
 
1459
1896
  if (strcmp(entry->name, cfg.ptr) == 0) {
@@ -1465,9 +1902,10 @@ static int check_valid_extension(const git_config_entry *entry, void *payload)
1465
1902
  }
1466
1903
 
1467
1904
  for (i = 0; i < ARRAY_SIZE(builtin_extensions); i++) {
1905
+ git_str_clear(&cfg);
1468
1906
  extension = builtin_extensions[i];
1469
1907
 
1470
- if ((error = git_buf_printf(&cfg, "extensions.%s", extension)) < 0)
1908
+ if ((error = git_str_printf(&cfg, "extensions.%s", extension)) < 0)
1471
1909
  goto done;
1472
1910
 
1473
1911
  if (strcmp(entry->name, cfg.ptr) == 0)
@@ -1479,7 +1917,7 @@ fail:
1479
1917
  error = -1;
1480
1918
 
1481
1919
  done:
1482
- git_buf_dispose(&cfg);
1920
+ git_str_dispose(&cfg);
1483
1921
  return error;
1484
1922
  }
1485
1923
 
@@ -1491,6 +1929,79 @@ static int check_extensions(git_config *config, int version)
1491
1929
  return git_config_foreach_match(config, "^extensions\\.", check_valid_extension, NULL);
1492
1930
  }
1493
1931
 
1932
+ static int load_objectformat(git_repository *repo, git_config *config)
1933
+ {
1934
+ git_config_entry *entry = NULL;
1935
+ int error;
1936
+
1937
+ if ((error = git_config_get_entry(&entry, config, "extensions.objectformat")) < 0) {
1938
+ if (error == GIT_ENOTFOUND) {
1939
+ repo->oid_type = GIT_OID_DEFAULT;
1940
+ git_error_clear();
1941
+ error = 0;
1942
+ }
1943
+
1944
+ goto done;
1945
+ }
1946
+
1947
+ if ((repo->oid_type = git_oid_type_fromstr(entry->value)) == 0) {
1948
+ git_error_set(GIT_ERROR_REPOSITORY,
1949
+ "unknown object format '%s'", entry->value);
1950
+ error = GIT_EINVALID;
1951
+ }
1952
+
1953
+ done:
1954
+ git_config_entry_free(entry);
1955
+ return error;
1956
+ }
1957
+
1958
+ int git_repository__set_objectformat(
1959
+ git_repository *repo,
1960
+ git_oid_t oid_type)
1961
+ {
1962
+ git_config *cfg;
1963
+
1964
+ /*
1965
+ * Older clients do not necessarily understand the
1966
+ * `objectformat` extension, even when it's set to an
1967
+ * object format that they understand (SHA1). Do not set
1968
+ * the objectformat extension unless we're not using the
1969
+ * default object format.
1970
+ */
1971
+ if (oid_type == GIT_OID_DEFAULT)
1972
+ return 0;
1973
+
1974
+ if (!git_repository_is_empty(repo) && repo->oid_type != oid_type) {
1975
+ git_error_set(GIT_ERROR_REPOSITORY,
1976
+ "cannot change object id type of existing repository");
1977
+ return -1;
1978
+ }
1979
+
1980
+ if (git_repository_config__weakptr(&cfg, repo) < 0)
1981
+ return -1;
1982
+
1983
+ if (git_config_set_int32(cfg,
1984
+ "core.repositoryformatversion", 1) < 0 ||
1985
+ git_config_set_string(cfg, "extensions.objectformat",
1986
+ git_oid_type_name(oid_type)) < 0)
1987
+ return -1;
1988
+
1989
+ /*
1990
+ * During repo init, we may create some backends with the
1991
+ * default oid type. Clear them so that we create them with
1992
+ * the proper oid type.
1993
+ */
1994
+ if (repo->oid_type != oid_type) {
1995
+ set_index(repo, NULL);
1996
+ set_odb(repo, NULL);
1997
+ set_refdb(repo, NULL);
1998
+
1999
+ repo->oid_type = oid_type;
2000
+ }
2001
+
2002
+ return 0;
2003
+ }
2004
+
1494
2005
  int git_repository__extensions(char ***out, size_t *out_len)
1495
2006
  {
1496
2007
  git_vector extensions;
@@ -1498,7 +2009,7 @@ int git_repository__extensions(char ***out, size_t *out_len)
1498
2009
  char *extension;
1499
2010
  size_t i, j;
1500
2011
 
1501
- if (git_vector_init(&extensions, 8, NULL) < 0)
2012
+ if (git_vector_init(&extensions, 8, git__strcmp_cb) < 0)
1502
2013
  return -1;
1503
2014
 
1504
2015
  for (i = 0; i < ARRAY_SIZE(builtin_extensions); i++) {
@@ -1530,21 +2041,49 @@ int git_repository__extensions(char ***out, size_t *out_len)
1530
2041
  return -1;
1531
2042
  }
1532
2043
 
2044
+ git_vector_sort(&extensions);
2045
+
1533
2046
  *out = (char **)git_vector_detach(out_len, NULL, &extensions);
1534
2047
  return 0;
1535
2048
  }
1536
2049
 
2050
+ static int dup_ext_err(void **old, void *extension)
2051
+ {
2052
+ GIT_UNUSED(old);
2053
+ GIT_UNUSED(extension);
2054
+ return GIT_EEXISTS;
2055
+ }
2056
+
1537
2057
  int git_repository__set_extensions(const char **extensions, size_t len)
1538
2058
  {
1539
2059
  char *extension;
1540
- size_t i;
2060
+ size_t i, j;
2061
+ int error;
1541
2062
 
1542
2063
  git_repository__free_extensions();
1543
2064
 
1544
2065
  for (i = 0; i < len; i++) {
1545
- if ((extension = git__strdup(extensions[i])) == NULL ||
1546
- git_vector_insert(&user_extensions, extension) < 0)
2066
+ bool is_builtin = false;
2067
+
2068
+ for (j = 0; j < ARRAY_SIZE(builtin_extensions); j++) {
2069
+ if (strcmp(builtin_extensions[j], extensions[i]) == 0) {
2070
+ is_builtin = true;
2071
+ break;
2072
+ }
2073
+ }
2074
+
2075
+ if (is_builtin)
2076
+ continue;
2077
+
2078
+ if ((extension = git__strdup(extensions[i])) == NULL)
1547
2079
  return -1;
2080
+
2081
+ if ((error = git_vector_insert_sorted(&user_extensions, extension, dup_ext_err)) < 0) {
2082
+ git__free(extension);
2083
+
2084
+ if (error != GIT_EEXISTS)
2085
+ return -1;
2086
+ }
1548
2087
  }
1549
2088
 
1550
2089
  return 0;
@@ -1552,17 +2091,17 @@ int git_repository__set_extensions(const char **extensions, size_t len)
1552
2091
 
1553
2092
  void git_repository__free_extensions(void)
1554
2093
  {
1555
- git_vector_free_deep(&user_extensions);
2094
+ git_vector_dispose_deep(&user_extensions);
1556
2095
  }
1557
2096
 
1558
2097
  int git_repository_create_head(const char *git_dir, const char *ref_name)
1559
2098
  {
1560
- git_buf ref_path = GIT_BUF_INIT;
2099
+ git_str ref_path = GIT_STR_INIT;
1561
2100
  git_filebuf ref = GIT_FILEBUF_INIT;
1562
2101
  const char *fmt;
1563
2102
  int error;
1564
2103
 
1565
- if ((error = git_buf_joinpath(&ref_path, git_dir, GIT_HEAD_FILE)) < 0 ||
2104
+ if ((error = git_str_joinpath(&ref_path, git_dir, GIT_HEAD_FILE)) < 0 ||
1566
2105
  (error = git_filebuf_open(&ref, ref_path.ptr, 0, GIT_REFS_FILE_MODE)) < 0)
1567
2106
  goto out;
1568
2107
 
@@ -1576,7 +2115,7 @@ int git_repository_create_head(const char *git_dir, const char *ref_name)
1576
2115
  goto out;
1577
2116
 
1578
2117
  out:
1579
- git_buf_dispose(&ref_path);
2118
+ git_str_dispose(&ref_path);
1580
2119
  git_filebuf_cleanup(&ref);
1581
2120
  return error;
1582
2121
  }
@@ -1599,23 +2138,51 @@ static bool is_chmod_supported(const char *file_path)
1599
2138
 
1600
2139
  static bool is_filesystem_case_insensitive(const char *gitdir_path)
1601
2140
  {
1602
- git_buf path = GIT_BUF_INIT;
2141
+ git_str path = GIT_STR_INIT;
1603
2142
  int is_insensitive = -1;
1604
2143
 
1605
- if (!git_buf_joinpath(&path, gitdir_path, "CoNfIg"))
1606
- is_insensitive = git_path_exists(git_buf_cstr(&path));
2144
+ if (!git_str_joinpath(&path, gitdir_path, "CoNfIg"))
2145
+ is_insensitive = git_fs_path_exists(git_str_cstr(&path));
1607
2146
 
1608
- git_buf_dispose(&path);
2147
+ git_str_dispose(&path);
1609
2148
  return is_insensitive;
1610
2149
  }
1611
2150
 
1612
- static bool are_symlinks_supported(const char *wd_path)
2151
+ /*
2152
+ * Return a configuration object with only the global and system
2153
+ * configurations; no repository-level configuration.
2154
+ */
2155
+ static int load_global_config(git_config **config, bool use_env)
2156
+ {
2157
+ git_str global_buf = GIT_STR_INIT;
2158
+ git_str xdg_buf = GIT_STR_INIT;
2159
+ git_str system_buf = GIT_STR_INIT;
2160
+ git_str programdata_buf = GIT_STR_INIT;
2161
+ int error;
2162
+
2163
+ if (!(error = config_path_system(&system_buf, use_env)) &&
2164
+ !(error = config_path_global(&global_buf, use_env))) {
2165
+ git_config__find_xdg(&xdg_buf);
2166
+ git_config__find_programdata(&programdata_buf);
2167
+
2168
+ error = load_config(config, NULL,
2169
+ path_unless_empty(&global_buf),
2170
+ path_unless_empty(&xdg_buf),
2171
+ path_unless_empty(&system_buf),
2172
+ path_unless_empty(&programdata_buf));
2173
+ }
2174
+
2175
+ git_str_dispose(&global_buf);
2176
+ git_str_dispose(&xdg_buf);
2177
+ git_str_dispose(&system_buf);
2178
+ git_str_dispose(&programdata_buf);
2179
+
2180
+ return error;
2181
+ }
2182
+
2183
+ static bool are_symlinks_supported(const char *wd_path, bool use_env)
1613
2184
  {
1614
2185
  git_config *config = NULL;
1615
- git_buf global_buf = GIT_BUF_INIT;
1616
- git_buf xdg_buf = GIT_BUF_INIT;
1617
- git_buf system_buf = GIT_BUF_INIT;
1618
- git_buf programdata_buf = GIT_BUF_INIT;
1619
2186
  int symlinks = 0;
1620
2187
 
1621
2188
  /*
@@ -1626,30 +2193,18 @@ static bool are_symlinks_supported(const char *wd_path)
1626
2193
  * _not_ set, then we do not test or enable symlink support.
1627
2194
  */
1628
2195
  #ifdef GIT_WIN32
1629
- git_config_find_global(&global_buf);
1630
- git_config_find_xdg(&xdg_buf);
1631
- git_config_find_system(&system_buf);
1632
- git_config_find_programdata(&programdata_buf);
1633
-
1634
- if (load_config(&config, NULL,
1635
- path_unless_empty(&global_buf),
1636
- path_unless_empty(&xdg_buf),
1637
- path_unless_empty(&system_buf),
1638
- path_unless_empty(&programdata_buf)) < 0)
1639
- goto done;
1640
-
1641
- if (git_config_get_bool(&symlinks, config, "core.symlinks") < 0 || !symlinks)
2196
+ if (load_global_config(&config, use_env) < 0 ||
2197
+ git_config_get_bool(&symlinks, config, "core.symlinks") < 0 ||
2198
+ !symlinks)
1642
2199
  goto done;
2200
+ #else
2201
+ GIT_UNUSED(use_env);
1643
2202
  #endif
1644
2203
 
1645
- if (!(symlinks = git_path_supports_symlinks(wd_path)))
2204
+ if (!(symlinks = git_fs_path_supports_symlinks(wd_path)))
1646
2205
  goto done;
1647
2206
 
1648
2207
  done:
1649
- git_buf_dispose(&global_buf);
1650
- git_buf_dispose(&xdg_buf);
1651
- git_buf_dispose(&system_buf);
1652
- git_buf_dispose(&programdata_buf);
1653
2208
  git_config_free(config);
1654
2209
  return symlinks != 0;
1655
2210
  }
@@ -1673,7 +2228,7 @@ static int create_empty_file(const char *path, mode_t mode)
1673
2228
 
1674
2229
  static int repo_local_config(
1675
2230
  git_config **out,
1676
- git_buf *config_dir,
2231
+ git_str *config_dir,
1677
2232
  git_repository *repo,
1678
2233
  const char *repo_dir)
1679
2234
  {
@@ -1681,12 +2236,12 @@ static int repo_local_config(
1681
2236
  git_config *parent;
1682
2237
  const char *cfg_path;
1683
2238
 
1684
- if (git_buf_joinpath(config_dir, repo_dir, GIT_CONFIG_FILENAME_INREPO) < 0)
2239
+ if (git_str_joinpath(config_dir, repo_dir, GIT_CONFIG_FILENAME_INREPO) < 0)
1685
2240
  return -1;
1686
- cfg_path = git_buf_cstr(config_dir);
2241
+ cfg_path = git_str_cstr(config_dir);
1687
2242
 
1688
2243
  /* make LOCAL config if missing */
1689
- if (!git_path_isfile(cfg_path) &&
2244
+ if (!git_fs_path_isfile(cfg_path) &&
1690
2245
  (error = create_empty_file(cfg_path, GIT_CONFIG_FILE_MODE)) < 0)
1691
2246
  return error;
1692
2247
 
@@ -1716,7 +2271,8 @@ static int repo_init_fs_configs(
1716
2271
  const char *cfg_path,
1717
2272
  const char *repo_dir,
1718
2273
  const char *work_dir,
1719
- bool update_ignorecase)
2274
+ bool update_ignorecase,
2275
+ bool use_env)
1720
2276
  {
1721
2277
  int error = 0;
1722
2278
 
@@ -1727,7 +2283,7 @@ static int repo_init_fs_configs(
1727
2283
  cfg, "core.filemode", is_chmod_supported(cfg_path))) < 0)
1728
2284
  return error;
1729
2285
 
1730
- if (!are_symlinks_supported(work_dir)) {
2286
+ if (!are_symlinks_supported(work_dir, use_env)) {
1731
2287
  if ((error = git_config_set_bool(cfg, "core.symlinks", false)) < 0)
1732
2288
  return error;
1733
2289
  } else if (git_config_delete_entry(cfg, "core.symlinks") < 0)
@@ -1744,7 +2300,7 @@ static int repo_init_fs_configs(
1744
2300
  #ifdef GIT_USE_ICONV
1745
2301
  if ((error = git_config_set_bool(
1746
2302
  cfg, "core.precomposeunicode",
1747
- git_path_does_fs_decompose_unicode(work_dir))) < 0)
2303
+ git_fs_path_does_decompose_unicode(work_dir))) < 0)
1748
2304
  return error;
1749
2305
  /* on non-iconv platforms, don't even set core.precomposeunicode */
1750
2306
  #endif
@@ -1756,19 +2312,22 @@ static int repo_init_config(
1756
2312
  const char *repo_dir,
1757
2313
  const char *work_dir,
1758
2314
  uint32_t flags,
1759
- uint32_t mode)
2315
+ uint32_t mode,
2316
+ git_oid_t oid_type)
1760
2317
  {
1761
2318
  int error = 0;
1762
- git_buf cfg_path = GIT_BUF_INIT, worktree_path = GIT_BUF_INIT;
2319
+ git_str cfg_path = GIT_STR_INIT, worktree_path = GIT_STR_INIT;
1763
2320
  git_config *config = NULL;
1764
2321
  bool is_bare = ((flags & GIT_REPOSITORY_INIT_BARE) != 0);
1765
2322
  bool is_reinit = ((flags & GIT_REPOSITORY_INIT__IS_REINIT) != 0);
1766
- int version = 0;
2323
+ bool use_env = ((flags & GIT_REPOSITORY_OPEN_FROM_ENV) != 0);
2324
+ int version = GIT_REPO_VERSION_DEFAULT;
1767
2325
 
1768
2326
  if ((error = repo_local_config(&config, &cfg_path, NULL, repo_dir)) < 0)
1769
2327
  goto cleanup;
1770
2328
 
1771
- if (is_reinit && (error = check_repositoryformatversion(&version, config)) < 0)
2329
+ if (is_reinit &&
2330
+ (error = check_repositoryformatversion(&version, config)) < 0)
1772
2331
  goto cleanup;
1773
2332
 
1774
2333
  if ((error = check_extensions(config, version)) < 0)
@@ -1779,21 +2338,22 @@ static int repo_init_config(
1779
2338
  goto cleanup; } while (0)
1780
2339
 
1781
2340
  SET_REPO_CONFIG(bool, "core.bare", is_bare);
1782
- SET_REPO_CONFIG(int32, "core.repositoryformatversion", GIT_REPO_VERSION);
2341
+ SET_REPO_CONFIG(int32, "core.repositoryformatversion", version);
1783
2342
 
1784
2343
  if ((error = repo_init_fs_configs(
1785
- config, cfg_path.ptr, repo_dir, work_dir, !is_reinit)) < 0)
2344
+ config, cfg_path.ptr, repo_dir, work_dir,
2345
+ !is_reinit, use_env)) < 0)
1786
2346
  goto cleanup;
1787
2347
 
1788
2348
  if (!is_bare) {
1789
2349
  SET_REPO_CONFIG(bool, "core.logallrefupdates", true);
1790
2350
 
1791
2351
  if (!(flags & GIT_REPOSITORY_INIT__NATURAL_WD)) {
1792
- if ((error = git_buf_sets(&worktree_path, work_dir)) < 0)
2352
+ if ((error = git_str_sets(&worktree_path, work_dir)) < 0)
1793
2353
  goto cleanup;
1794
2354
 
1795
2355
  if ((flags & GIT_REPOSITORY_INIT_RELATIVE_GITLINK))
1796
- if ((error = git_path_make_relative(&worktree_path, repo_dir)) < 0)
2356
+ if ((error = git_fs_path_make_relative(&worktree_path, repo_dir)) < 0)
1797
2357
  goto cleanup;
1798
2358
 
1799
2359
  SET_REPO_CONFIG(string, "core.worktree", worktree_path.ptr);
@@ -1812,9 +2372,14 @@ static int repo_init_config(
1812
2372
  SET_REPO_CONFIG(bool, "receive.denyNonFastforwards", true);
1813
2373
  }
1814
2374
 
2375
+ if (oid_type != GIT_OID_DEFAULT) {
2376
+ SET_REPO_CONFIG(int32, "core.repositoryformatversion", 1);
2377
+ SET_REPO_CONFIG(string, "extensions.objectformat", git_oid_type_name(oid_type));
2378
+ }
2379
+
1815
2380
  cleanup:
1816
- git_buf_dispose(&cfg_path);
1817
- git_buf_dispose(&worktree_path);
2381
+ git_str_dispose(&cfg_path);
2382
+ git_str_dispose(&worktree_path);
1818
2383
  git_config_free(config);
1819
2384
 
1820
2385
  return error;
@@ -1836,16 +2401,16 @@ static int repo_reinit_submodule_fs(git_submodule *sm, const char *n, void *p)
1836
2401
  int git_repository_reinit_filesystem(git_repository *repo, int recurse)
1837
2402
  {
1838
2403
  int error = 0;
1839
- git_buf path = GIT_BUF_INIT;
2404
+ git_str path = GIT_STR_INIT;
1840
2405
  git_config *config = NULL;
1841
2406
  const char *repo_dir = git_repository_path(repo);
1842
2407
 
1843
2408
  if (!(error = repo_local_config(&config, &path, repo, repo_dir)))
1844
- error = repo_init_fs_configs(
1845
- config, path.ptr, repo_dir, git_repository_workdir(repo), true);
2409
+ error = repo_init_fs_configs(config, path.ptr, repo_dir,
2410
+ git_repository_workdir(repo), true, repo->use_env);
1846
2411
 
1847
2412
  git_config_free(config);
1848
- git_buf_dispose(&path);
2413
+ git_str_dispose(&path);
1849
2414
 
1850
2415
  git_repository__configmap_lookup_cache_clear(repo);
1851
2416
 
@@ -1863,10 +2428,10 @@ static int repo_write_template(
1863
2428
  bool hidden,
1864
2429
  const char *content)
1865
2430
  {
1866
- git_buf path = GIT_BUF_INIT;
2431
+ git_str path = GIT_STR_INIT;
1867
2432
  int fd, error = 0, flags;
1868
2433
 
1869
- if (git_buf_joinpath(&path, git_dir, file) < 0)
2434
+ if (git_str_joinpath(&path, git_dir, file) < 0)
1870
2435
  return -1;
1871
2436
 
1872
2437
  if (allow_overwrite)
@@ -1874,7 +2439,7 @@ static int repo_write_template(
1874
2439
  else
1875
2440
  flags = O_WRONLY | O_CREAT | O_EXCL;
1876
2441
 
1877
- fd = p_open(git_buf_cstr(&path), flags, mode);
2442
+ fd = p_open(git_str_cstr(&path), flags, mode);
1878
2443
 
1879
2444
  if (fd >= 0) {
1880
2445
  error = p_write(fd, content, strlen(content));
@@ -1893,7 +2458,7 @@ static int repo_write_template(
1893
2458
  GIT_UNUSED(hidden);
1894
2459
  #endif
1895
2460
 
1896
- git_buf_dispose(&path);
2461
+ git_str_dispose(&path);
1897
2462
 
1898
2463
  if (error)
1899
2464
  git_error_set(GIT_ERROR_OS,
@@ -1906,13 +2471,13 @@ static int repo_write_gitlink(
1906
2471
  const char *in_dir, const char *to_repo, bool use_relative_path)
1907
2472
  {
1908
2473
  int error;
1909
- git_buf buf = GIT_BUF_INIT;
1910
- git_buf path_to_repo = GIT_BUF_INIT;
2474
+ git_str buf = GIT_STR_INIT;
2475
+ git_str path_to_repo = GIT_STR_INIT;
1911
2476
  struct stat st;
1912
2477
 
1913
- git_path_dirname_r(&buf, to_repo);
1914
- git_path_to_dir(&buf);
1915
- if (git_buf_oom(&buf))
2478
+ git_fs_path_dirname_r(&buf, to_repo);
2479
+ git_fs_path_to_dir(&buf);
2480
+ if (git_str_oom(&buf))
1916
2481
  return -1;
1917
2482
 
1918
2483
  /* don't write gitlink to natural workdir */
@@ -1923,7 +2488,7 @@ static int repo_write_gitlink(
1923
2488
  goto cleanup;
1924
2489
  }
1925
2490
 
1926
- if ((error = git_buf_joinpath(&buf, in_dir, DOT_GIT)) < 0)
2491
+ if ((error = git_str_joinpath(&buf, in_dir, DOT_GIT)) < 0)
1927
2492
  goto cleanup;
1928
2493
 
1929
2494
  if (!p_stat(buf.ptr, &st) && !S_ISREG(st.st_mode)) {
@@ -1933,22 +2498,22 @@ static int repo_write_gitlink(
1933
2498
  goto cleanup;
1934
2499
  }
1935
2500
 
1936
- git_buf_clear(&buf);
2501
+ git_str_clear(&buf);
1937
2502
 
1938
- error = git_buf_sets(&path_to_repo, to_repo);
2503
+ error = git_str_sets(&path_to_repo, to_repo);
1939
2504
 
1940
2505
  if (!error && use_relative_path)
1941
- error = git_path_make_relative(&path_to_repo, in_dir);
2506
+ error = git_fs_path_make_relative(&path_to_repo, in_dir);
1942
2507
 
1943
2508
  if (!error)
1944
- error = git_buf_join(&buf, ' ', GIT_FILE_CONTENT_PREFIX, path_to_repo.ptr);
2509
+ error = git_str_printf(&buf, "%s %s\n", GIT_FILE_CONTENT_PREFIX, path_to_repo.ptr);
1945
2510
 
1946
2511
  if (!error)
1947
2512
  error = repo_write_template(in_dir, true, DOT_GIT, 0666, true, buf.ptr);
1948
2513
 
1949
2514
  cleanup:
1950
- git_buf_dispose(&buf);
1951
- git_buf_dispose(&path_to_repo);
2515
+ git_str_dispose(&buf);
2516
+ git_str_dispose(&path_to_repo);
1952
2517
  return error;
1953
2518
  }
1954
2519
 
@@ -1973,7 +2538,8 @@ static int repo_init_structure(
1973
2538
  int error = 0;
1974
2539
  repo_template_item *tpl;
1975
2540
  bool external_tpl =
1976
- ((opts->flags & GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE) != 0);
2541
+ opts->template_path != NULL ||
2542
+ (opts->flags & GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE) != 0;
1977
2543
  mode_t dmode = pick_dir_mode(opts);
1978
2544
  bool chmod = opts->mode != GIT_REPOSITORY_INIT_SHARED_UMASK;
1979
2545
 
@@ -2001,12 +2567,12 @@ static int repo_init_structure(
2001
2567
  git_config *cfg = NULL;
2002
2568
  const char *tdir = NULL;
2003
2569
  bool default_template = false;
2004
- git_buf template_buf = GIT_BUF_INIT;
2570
+ git_str template_buf = GIT_STR_INIT;
2005
2571
 
2006
2572
  if (opts->template_path)
2007
2573
  tdir = opts->template_path;
2008
2574
  else if ((error = git_config_open_default(&cfg)) >= 0) {
2009
- if (!git_config_get_path(&template_buf, cfg, "init.templatedir"))
2575
+ if (!git_config__get_path(&template_buf, cfg, "init.templatedir"))
2010
2576
  tdir = template_buf.ptr;
2011
2577
  git_error_clear();
2012
2578
  }
@@ -2032,11 +2598,16 @@ static int repo_init_structure(
2032
2598
  error = git_futils_cp_r(tdir, repo_dir, cpflags, dmode);
2033
2599
  }
2034
2600
 
2035
- git_buf_dispose(&template_buf);
2601
+ git_str_dispose(&template_buf);
2036
2602
  git_config_free(cfg);
2037
2603
 
2604
+ /* If tdir does not exist, then do not error out. This matches the
2605
+ * behaviour of git(1), which just prints a warning and continues.
2606
+ * TODO: issue warning when warning API is available.
2607
+ * `git` prints to stderr: 'warning: templates not found in /path/to/tdir'
2608
+ */
2038
2609
  if (error < 0) {
2039
- if (!default_template)
2610
+ if (!default_template && error != GIT_ENOTFOUND)
2040
2611
  return error;
2041
2612
 
2042
2613
  /* if template was default, ignore error and use internal */
@@ -2073,7 +2644,7 @@ static int repo_init_structure(
2073
2644
  return error;
2074
2645
  }
2075
2646
 
2076
- static int mkdir_parent(git_buf *buf, uint32_t mode, bool skip2)
2647
+ static int mkdir_parent(git_str *buf, uint32_t mode, bool skip2)
2077
2648
  {
2078
2649
  /* When making parent directories during repository initialization
2079
2650
  * don't try to set gid or grant world write access
@@ -2085,8 +2656,8 @@ static int mkdir_parent(git_buf *buf, uint32_t mode, bool skip2)
2085
2656
  }
2086
2657
 
2087
2658
  static int repo_init_directories(
2088
- git_buf *repo_path,
2089
- git_buf *wd_path,
2659
+ git_str *repo_path,
2660
+ git_str *wd_path,
2090
2661
  const char *given_repo,
2091
2662
  git_repository_init_options *opts)
2092
2663
  {
@@ -2124,9 +2695,11 @@ static int repo_init_directories(
2124
2695
  git__suffixcmp(given_repo, "/" DOT_GIT) != 0 &&
2125
2696
  git__suffixcmp(given_repo, "/" GIT_DIR) != 0;
2126
2697
 
2127
- if (git_buf_joinpath(repo_path, given_repo, add_dotgit ? GIT_DIR : "") < 0)
2698
+ if (git_str_joinpath(repo_path, given_repo, add_dotgit ? GIT_DIR : "") < 0)
2128
2699
  return -1;
2129
2700
 
2701
+ git_fs_path_mkposix(repo_path->ptr);
2702
+
2130
2703
  has_dotgit = (git__suffixcmp(repo_path->ptr, "/" GIT_DIR) == 0);
2131
2704
  if (has_dotgit)
2132
2705
  opts->flags |= GIT_REPOSITORY_INIT__HAS_DOTGIT;
@@ -2135,11 +2708,11 @@ static int repo_init_directories(
2135
2708
 
2136
2709
  if (!is_bare) {
2137
2710
  if (opts->workdir_path) {
2138
- if (git_path_join_unrooted(
2711
+ if (git_fs_path_join_unrooted(
2139
2712
  wd_path, opts->workdir_path, repo_path->ptr, NULL) < 0)
2140
2713
  return -1;
2141
2714
  } else if (has_dotgit) {
2142
- if (git_path_dirname_r(wd_path, repo_path->ptr) < 0)
2715
+ if (git_fs_path_dirname_r(wd_path, repo_path->ptr) < 0)
2143
2716
  return -1;
2144
2717
  } else {
2145
2718
  git_error_set(GIT_ERROR_REPOSITORY, "cannot pick working directory"
@@ -2147,10 +2720,10 @@ static int repo_init_directories(
2147
2720
  return -1;
2148
2721
  }
2149
2722
 
2150
- if (git_path_to_dir(wd_path) < 0)
2723
+ if (git_fs_path_to_dir(wd_path) < 0)
2151
2724
  return -1;
2152
2725
  } else {
2153
- git_buf_clear(wd_path);
2726
+ git_str_clear(wd_path);
2154
2727
  }
2155
2728
 
2156
2729
  natural_wd =
@@ -2207,10 +2780,10 @@ static int repo_init_directories(
2207
2780
  /* prettify both directories now that they are created */
2208
2781
 
2209
2782
  if (!error) {
2210
- error = git_path_prettify_dir(repo_path, repo_path->ptr, NULL);
2783
+ error = git_fs_path_prettify_dir(repo_path, repo_path->ptr, NULL);
2211
2784
 
2212
2785
  if (!error && wd_path->size > 0)
2213
- error = git_path_prettify_dir(wd_path, wd_path->ptr, NULL);
2786
+ error = git_fs_path_prettify_dir(wd_path, wd_path->ptr, NULL);
2214
2787
  }
2215
2788
 
2216
2789
  return error;
@@ -2219,24 +2792,24 @@ static int repo_init_directories(
2219
2792
  static int repo_init_head(const char *repo_dir, const char *given)
2220
2793
  {
2221
2794
  git_config *cfg = NULL;
2222
- git_buf head_path = GIT_BUF_INIT, cfg_branch = GIT_BUF_INIT;
2795
+ git_str head_path = GIT_STR_INIT, cfg_branch = GIT_STR_INIT;
2223
2796
  const char *initial_head = NULL;
2224
2797
  int error;
2225
2798
 
2226
- if ((error = git_buf_joinpath(&head_path, repo_dir, GIT_HEAD_FILE)) < 0)
2799
+ if ((error = git_str_joinpath(&head_path, repo_dir, GIT_HEAD_FILE)) < 0)
2227
2800
  goto out;
2228
2801
 
2229
2802
  /*
2230
2803
  * A template may have set a HEAD; use that unless it's been
2231
2804
  * overridden by the caller's given initial head setting.
2232
2805
  */
2233
- if (git_path_exists(head_path.ptr) && !given)
2806
+ if (git_fs_path_exists(head_path.ptr) && !given)
2234
2807
  goto out;
2235
2808
 
2236
2809
  if (given) {
2237
2810
  initial_head = given;
2238
2811
  } else if ((error = git_config_open_default(&cfg)) >= 0 &&
2239
- (error = git_config_get_string_buf(&cfg_branch, cfg, "init.defaultbranch")) >= 0 &&
2812
+ (error = git_config__get_string_buf(&cfg_branch, cfg, "init.defaultbranch")) >= 0 &&
2240
2813
  *cfg_branch.ptr) {
2241
2814
  initial_head = cfg_branch.ptr;
2242
2815
  }
@@ -2248,8 +2821,8 @@ static int repo_init_head(const char *repo_dir, const char *given)
2248
2821
 
2249
2822
  out:
2250
2823
  git_config_free(cfg);
2251
- git_buf_dispose(&head_path);
2252
- git_buf_dispose(&cfg_branch);
2824
+ git_str_dispose(&head_path);
2825
+ git_str_dispose(&cfg_branch);
2253
2826
 
2254
2827
  return error;
2255
2828
  }
@@ -2283,10 +2856,11 @@ int git_repository_init_ext(
2283
2856
  const char *given_repo,
2284
2857
  git_repository_init_options *opts)
2285
2858
  {
2286
- git_buf repo_path = GIT_BUF_INIT, wd_path = GIT_BUF_INIT,
2287
- common_path = GIT_BUF_INIT;
2859
+ git_str repo_path = GIT_STR_INIT, wd_path = GIT_STR_INIT,
2860
+ common_path = GIT_STR_INIT;
2288
2861
  const char *wd;
2289
2862
  bool is_valid;
2863
+ git_oid_t oid_type = GIT_OID_DEFAULT;
2290
2864
  int error;
2291
2865
 
2292
2866
  GIT_ASSERT_ARG(out);
@@ -2295,12 +2869,17 @@ int git_repository_init_ext(
2295
2869
 
2296
2870
  GIT_ERROR_CHECK_VERSION(opts, GIT_REPOSITORY_INIT_OPTIONS_VERSION, "git_repository_init_options");
2297
2871
 
2872
+ #ifdef GIT_EXPERIMENTAL_SHA256
2873
+ if (opts->oid_type)
2874
+ oid_type = opts->oid_type;
2875
+ #endif
2876
+
2298
2877
  if ((error = repo_init_directories(&repo_path, &wd_path, given_repo, opts)) < 0)
2299
2878
  goto out;
2300
2879
 
2301
- wd = (opts->flags & GIT_REPOSITORY_INIT_BARE) ? NULL : git_buf_cstr(&wd_path);
2880
+ wd = (opts->flags & GIT_REPOSITORY_INIT_BARE) ? NULL : git_str_cstr(&wd_path);
2302
2881
 
2303
- if ((error = is_valid_repository_path(&is_valid, &repo_path, &common_path)) < 0)
2882
+ if ((error = is_valid_repository_path(&is_valid, &repo_path, &common_path, opts->flags)) < 0)
2304
2883
  goto out;
2305
2884
 
2306
2885
  if (is_valid) {
@@ -2313,13 +2892,13 @@ int git_repository_init_ext(
2313
2892
 
2314
2893
  opts->flags |= GIT_REPOSITORY_INIT__IS_REINIT;
2315
2894
 
2316
- if ((error = repo_init_config(repo_path.ptr, wd, opts->flags, opts->mode)) < 0)
2895
+ if ((error = repo_init_config(repo_path.ptr, wd, opts->flags, opts->mode, oid_type)) < 0)
2317
2896
  goto out;
2318
2897
 
2319
2898
  /* TODO: reinitialize the templates */
2320
2899
  } else {
2321
2900
  if ((error = repo_init_structure(repo_path.ptr, wd, opts)) < 0 ||
2322
- (error = repo_init_config(repo_path.ptr, wd, opts->flags, opts->mode)) < 0 ||
2901
+ (error = repo_init_config(repo_path.ptr, wd, opts->flags, opts->mode, oid_type)) < 0 ||
2323
2902
  (error = repo_init_head(repo_path.ptr, opts->initial_head)) < 0)
2324
2903
  goto out;
2325
2904
  }
@@ -2332,9 +2911,9 @@ int git_repository_init_ext(
2332
2911
  goto out;
2333
2912
 
2334
2913
  out:
2335
- git_buf_dispose(&common_path);
2336
- git_buf_dispose(&repo_path);
2337
- git_buf_dispose(&wd_path);
2914
+ git_str_dispose(&common_path);
2915
+ git_str_dispose(&repo_path);
2916
+ git_str_dispose(&wd_path);
2338
2917
 
2339
2918
  return error;
2340
2919
  }
@@ -2522,7 +3101,7 @@ static int repo_contains_no_reference(git_repository *repo)
2522
3101
  return error;
2523
3102
  }
2524
3103
 
2525
- int git_repository_initialbranch(git_buf *out, git_repository *repo)
3104
+ int git_repository_initialbranch(git_str *out, git_repository *repo)
2526
3105
  {
2527
3106
  git_config *config;
2528
3107
  git_config_entry *entry = NULL;
@@ -2543,8 +3122,8 @@ int git_repository_initialbranch(git_buf *out, git_repository *repo)
2543
3122
  goto done;
2544
3123
  }
2545
3124
 
2546
- if ((error = git_buf_puts(out, GIT_REFS_HEADS_DIR)) < 0 ||
2547
- (error = git_buf_puts(out, branch)) < 0 ||
3125
+ if ((error = git_str_puts(out, GIT_REFS_HEADS_DIR)) < 0 ||
3126
+ (error = git_str_puts(out, branch)) < 0 ||
2548
3127
  (error = git_reference_name_is_valid(&valid, out->ptr)) < 0)
2549
3128
  goto done;
2550
3129
 
@@ -2561,7 +3140,7 @@ done:
2561
3140
  int git_repository_is_empty(git_repository *repo)
2562
3141
  {
2563
3142
  git_reference *head = NULL;
2564
- git_buf initialbranch = GIT_BUF_INIT;
3143
+ git_str initialbranch = GIT_STR_INIT;
2565
3144
  int result = 0;
2566
3145
 
2567
3146
  if ((result = git_reference_lookup(&head, repo, GIT_HEAD_FILE)) < 0 ||
@@ -2574,7 +3153,7 @@ int git_repository_is_empty(git_repository *repo)
2574
3153
 
2575
3154
  done:
2576
3155
  git_reference_free(head);
2577
- git_buf_dispose(&initialbranch);
3156
+ git_str_dispose(&initialbranch);
2578
3157
 
2579
3158
  return result;
2580
3159
  }
@@ -2603,7 +3182,18 @@ static const char *resolved_parent_path(const git_repository *repo, git_reposito
2603
3182
  return parent;
2604
3183
  }
2605
3184
 
2606
- int git_repository_item_path(git_buf *out, const git_repository *repo, git_repository_item_t item)
3185
+ int git_repository_item_path(
3186
+ git_buf *out,
3187
+ const git_repository *repo,
3188
+ git_repository_item_t item)
3189
+ {
3190
+ GIT_BUF_WRAP_PRIVATE(out, git_repository__item_path, repo, item);
3191
+ }
3192
+
3193
+ int git_repository__item_path(
3194
+ git_str *out,
3195
+ const git_repository *repo,
3196
+ git_repository_item_t item)
2607
3197
  {
2608
3198
  const char *parent = resolved_parent_path(repo, items[item].parent, items[item].fallback);
2609
3199
  if (parent == NULL) {
@@ -2611,16 +3201,16 @@ int git_repository_item_path(git_buf *out, const git_repository *repo, git_repos
2611
3201
  return GIT_ENOTFOUND;
2612
3202
  }
2613
3203
 
2614
- if (git_buf_sets(out, parent) < 0)
3204
+ if (git_str_sets(out, parent) < 0)
2615
3205
  return -1;
2616
3206
 
2617
3207
  if (items[item].name) {
2618
- if (git_buf_joinpath(out, parent, items[item].name) < 0)
3208
+ if (git_str_joinpath(out, parent, items[item].name) < 0)
2619
3209
  return -1;
2620
3210
  }
2621
3211
 
2622
3212
  if (items[item].directory) {
2623
- if (git_path_to_dir(out) < 0)
3213
+ if (git_fs_path_to_dir(out) < 0)
2624
3214
  return -1;
2625
3215
  }
2626
3216
 
@@ -2644,7 +3234,7 @@ const char *git_repository_workdir(const git_repository *repo)
2644
3234
  }
2645
3235
 
2646
3236
  int git_repository_workdir_path(
2647
- git_buf *out, git_repository *repo, const char *path)
3237
+ git_str *out, git_repository *repo, const char *path)
2648
3238
  {
2649
3239
  int error;
2650
3240
 
@@ -2653,8 +3243,8 @@ int git_repository_workdir_path(
2653
3243
  return GIT_EBAREREPO;
2654
3244
  }
2655
3245
 
2656
- if (!(error = git_buf_joinpath(out, repo->workdir, path)))
2657
- error = git_path_validate_workdir_buf(repo, out);
3246
+ if (!(error = git_str_joinpath(out, repo->workdir, path)))
3247
+ error = git_path_validate_str_length(repo, out);
2658
3248
 
2659
3249
  return error;
2660
3250
  }
@@ -2669,22 +3259,26 @@ int git_repository_set_workdir(
2669
3259
  git_repository *repo, const char *workdir, int update_gitlink)
2670
3260
  {
2671
3261
  int error = 0;
2672
- git_buf path = GIT_BUF_INIT;
3262
+ git_str path = GIT_STR_INIT;
2673
3263
 
2674
3264
  GIT_ASSERT_ARG(repo);
2675
3265
  GIT_ASSERT_ARG(workdir);
2676
3266
 
2677
- if (git_path_prettify_dir(&path, workdir, NULL) < 0)
3267
+ if (git_fs_path_prettify_dir(&path, workdir, NULL) < 0)
2678
3268
  return -1;
2679
3269
 
2680
- if (repo->workdir && strcmp(repo->workdir, path.ptr) == 0)
3270
+ if (repo->workdir && strcmp(repo->workdir, path.ptr) == 0) {
3271
+ git_str_dispose(&path);
2681
3272
  return 0;
3273
+ }
2682
3274
 
2683
3275
  if (update_gitlink) {
2684
3276
  git_config *config;
2685
3277
 
2686
- if (git_repository_config__weakptr(&config, repo) < 0)
3278
+ if (git_repository_config__weakptr(&config, repo) < 0) {
3279
+ git_str_dispose(&path);
2687
3280
  return -1;
3281
+ }
2688
3282
 
2689
3283
  error = repo_write_gitlink(path.ptr, git_repository_path(repo), false);
2690
3284
 
@@ -2701,11 +3295,12 @@ int git_repository_set_workdir(
2701
3295
  if (!error) {
2702
3296
  char *old_workdir = repo->workdir;
2703
3297
 
2704
- repo->workdir = git_buf_detach(&path);
3298
+ repo->workdir = git_str_detach(&path);
2705
3299
  repo->is_bare = 0;
2706
3300
 
2707
3301
  git__free(old_workdir);
2708
3302
  }
3303
+ git_str_dispose(&path);
2709
3304
 
2710
3305
  return error;
2711
3306
  }
@@ -2748,6 +3343,25 @@ int git_repository_set_bare(git_repository *repo)
2748
3343
  return 0;
2749
3344
  }
2750
3345
 
3346
+ int git_repository_head_commit(git_commit **commit, git_repository *repo)
3347
+ {
3348
+ git_reference *head;
3349
+ git_object *obj;
3350
+ int error;
3351
+
3352
+ if ((error = git_repository_head(&head, repo)) < 0)
3353
+ return error;
3354
+
3355
+ if ((error = git_reference_peel(&obj, head, GIT_OBJECT_COMMIT)) < 0)
3356
+ goto cleanup;
3357
+
3358
+ *commit = (git_commit *)obj;
3359
+
3360
+ cleanup:
3361
+ git_reference_free(head);
3362
+ return error;
3363
+ }
3364
+
2751
3365
  int git_repository_head_tree(git_tree **tree, git_repository *repo)
2752
3366
  {
2753
3367
  git_reference *head;
@@ -2770,60 +3384,62 @@ cleanup:
2770
3384
  int git_repository__set_orig_head(git_repository *repo, const git_oid *orig_head)
2771
3385
  {
2772
3386
  git_filebuf file = GIT_FILEBUF_INIT;
2773
- git_buf file_path = GIT_BUF_INIT;
2774
- char orig_head_str[GIT_OID_HEXSZ];
3387
+ git_str file_path = GIT_STR_INIT;
3388
+ char orig_head_str[GIT_OID_MAX_HEXSIZE];
2775
3389
  int error = 0;
2776
3390
 
2777
3391
  git_oid_fmt(orig_head_str, orig_head);
2778
3392
 
2779
- if ((error = git_buf_joinpath(&file_path, repo->gitdir, GIT_ORIG_HEAD_FILE)) == 0 &&
3393
+ if ((error = git_str_joinpath(&file_path, repo->gitdir, GIT_ORIG_HEAD_FILE)) == 0 &&
2780
3394
  (error = git_filebuf_open(&file, file_path.ptr, GIT_FILEBUF_CREATE_LEADING_DIRS, GIT_MERGE_FILE_MODE)) == 0 &&
2781
- (error = git_filebuf_printf(&file, "%.*s\n", GIT_OID_HEXSZ, orig_head_str)) == 0)
3395
+ (error = git_filebuf_printf(&file, "%.*s\n", (int)git_oid_hexsize(repo->oid_type), orig_head_str)) == 0)
2782
3396
  error = git_filebuf_commit(&file);
2783
3397
 
2784
3398
  if (error < 0)
2785
3399
  git_filebuf_cleanup(&file);
2786
3400
 
2787
- git_buf_dispose(&file_path);
3401
+ git_str_dispose(&file_path);
2788
3402
 
2789
3403
  return error;
2790
3404
  }
2791
3405
 
2792
- int git_repository_message(git_buf *out, git_repository *repo)
3406
+ static int git_repository__message(git_str *out, git_repository *repo)
2793
3407
  {
2794
- git_buf path = GIT_BUF_INIT;
3408
+ git_str path = GIT_STR_INIT;
2795
3409
  struct stat st;
2796
3410
  int error;
2797
3411
 
2798
- if ((error = git_buf_sanitize(out)) < 0)
2799
- return error;
2800
-
2801
- if (git_buf_joinpath(&path, repo->gitdir, GIT_MERGE_MSG_FILE) < 0)
3412
+ if (git_str_joinpath(&path, repo->gitdir, GIT_MERGE_MSG_FILE) < 0)
2802
3413
  return -1;
2803
3414
 
2804
- if ((error = p_stat(git_buf_cstr(&path), &st)) < 0) {
3415
+ if ((error = p_stat(git_str_cstr(&path), &st)) < 0) {
2805
3416
  if (errno == ENOENT)
2806
3417
  error = GIT_ENOTFOUND;
2807
3418
  git_error_set(GIT_ERROR_OS, "could not access message file");
2808
3419
  } else {
2809
- error = git_futils_readbuffer(out, git_buf_cstr(&path));
3420
+ error = git_futils_readbuffer(out, git_str_cstr(&path));
2810
3421
  }
2811
3422
 
2812
- git_buf_dispose(&path);
3423
+ git_str_dispose(&path);
2813
3424
 
2814
3425
  return error;
2815
3426
  }
2816
3427
 
3428
+ int git_repository_message(git_buf *out, git_repository *repo)
3429
+ {
3430
+ GIT_BUF_WRAP_PRIVATE(out, git_repository__message, repo);
3431
+ }
3432
+
2817
3433
  int git_repository_message_remove(git_repository *repo)
2818
3434
  {
2819
- git_buf path = GIT_BUF_INIT;
3435
+ git_str path = GIT_STR_INIT;
2820
3436
  int error;
2821
3437
 
2822
- if (git_buf_joinpath(&path, repo->gitdir, GIT_MERGE_MSG_FILE) < 0)
3438
+ if (git_str_joinpath(&path, repo->gitdir, GIT_MERGE_MSG_FILE) < 0)
2823
3439
  return -1;
2824
3440
 
2825
- error = p_unlink(git_buf_cstr(&path));
2826
- git_buf_dispose(&path);
3441
+ error = p_unlink(git_str_cstr(&path));
3442
+ git_str_dispose(&path);
2827
3443
 
2828
3444
  return error;
2829
3445
  }
@@ -2839,7 +3455,7 @@ int git_repository_hashfile(
2839
3455
  git_filter_list *fl = NULL;
2840
3456
  git_file fd = -1;
2841
3457
  uint64_t len;
2842
- git_buf full_path = GIT_BUF_INIT;
3458
+ git_str full_path = GIT_STR_INIT;
2843
3459
  const char *workdir = git_repository_workdir(repo);
2844
3460
 
2845
3461
  /* as_path can be NULL */
@@ -2847,8 +3463,8 @@ int git_repository_hashfile(
2847
3463
  GIT_ASSERT_ARG(path);
2848
3464
  GIT_ASSERT_ARG(repo);
2849
3465
 
2850
- if ((error = git_path_join_unrooted(&full_path, path, workdir, NULL)) < 0 ||
2851
- (error = git_path_validate_workdir_buf(repo, &full_path)) < 0)
3466
+ if ((error = git_fs_path_join_unrooted(&full_path, path, workdir, NULL)) < 0 ||
3467
+ (error = git_path_validate_str_length(repo, &full_path)) < 0)
2852
3468
  return error;
2853
3469
 
2854
3470
  /*
@@ -2889,36 +3505,42 @@ int git_repository_hashfile(
2889
3505
  goto cleanup;
2890
3506
  }
2891
3507
 
2892
- error = git_odb__hashfd_filtered(out, fd, (size_t)len, type, fl);
3508
+ error = git_odb__hashfd_filtered(out, fd, (size_t)len, type, repo->oid_type, fl);
2893
3509
 
2894
3510
  cleanup:
2895
3511
  if (fd >= 0)
2896
3512
  p_close(fd);
2897
3513
  git_filter_list_free(fl);
2898
- git_buf_dispose(&full_path);
3514
+ git_str_dispose(&full_path);
2899
3515
 
2900
3516
  return error;
2901
3517
  }
2902
3518
 
2903
- static int checkout_message(git_buf *out, git_reference *old, const char *new)
3519
+ static int checkout_message(git_str *out, git_reference *old, const char *new)
2904
3520
  {
2905
- git_buf_puts(out, "checkout: moving from ");
3521
+ const char *idstr;
2906
3522
 
2907
- if (git_reference_type(old) == GIT_REFERENCE_SYMBOLIC)
2908
- git_buf_puts(out, git_reference__shorthand(git_reference_symbolic_target(old)));
2909
- else
2910
- git_buf_puts(out, git_oid_tostr_s(git_reference_target(old)));
3523
+ git_str_puts(out, "checkout: moving from ");
3524
+
3525
+ if (git_reference_type(old) == GIT_REFERENCE_SYMBOLIC) {
3526
+ git_str_puts(out, git_reference__shorthand(git_reference_symbolic_target(old)));
3527
+ } else {
3528
+ if ((idstr = git_oid_tostr_s(git_reference_target(old))) == NULL)
3529
+ return -1;
3530
+
3531
+ git_str_puts(out, idstr);
3532
+ }
2911
3533
 
2912
- git_buf_puts(out, " to ");
3534
+ git_str_puts(out, " to ");
2913
3535
 
2914
3536
  if (git_reference__is_branch(new) ||
2915
3537
  git_reference__is_tag(new) ||
2916
3538
  git_reference__is_remote(new))
2917
- git_buf_puts(out, git_reference__shorthand(new));
3539
+ git_str_puts(out, git_reference__shorthand(new));
2918
3540
  else
2919
- git_buf_puts(out, new);
3541
+ git_str_puts(out, new);
2920
3542
 
2921
- if (git_buf_oom(out))
3543
+ if (git_str_oom(out))
2922
3544
  return -1;
2923
3545
 
2924
3546
  return 0;
@@ -2927,7 +3549,7 @@ static int checkout_message(git_buf *out, git_reference *old, const char *new)
2927
3549
  static int detach(git_repository *repo, const git_oid *id, const char *new)
2928
3550
  {
2929
3551
  int error;
2930
- git_buf log_message = GIT_BUF_INIT;
3552
+ git_str log_message = GIT_STR_INIT;
2931
3553
  git_object *object = NULL, *peeled = NULL;
2932
3554
  git_reference *new_head = NULL, *current = NULL;
2933
3555
 
@@ -2943,16 +3565,19 @@ static int detach(git_repository *repo, const git_oid *id, const char *new)
2943
3565
  if ((error = git_object_peel(&peeled, object, GIT_OBJECT_COMMIT)) < 0)
2944
3566
  goto cleanup;
2945
3567
 
2946
- if (new == NULL)
2947
- new = git_oid_tostr_s(git_object_id(peeled));
3568
+ if (new == NULL &&
3569
+ (new = git_oid_tostr_s(git_object_id(peeled))) == NULL) {
3570
+ error = -1;
3571
+ goto cleanup;
3572
+ }
2948
3573
 
2949
3574
  if ((error = checkout_message(&log_message, current, new)) < 0)
2950
3575
  goto cleanup;
2951
3576
 
2952
- error = git_reference_create(&new_head, repo, GIT_HEAD_FILE, git_object_id(peeled), true, git_buf_cstr(&log_message));
3577
+ error = git_reference_create(&new_head, repo, GIT_HEAD_FILE, git_object_id(peeled), true, git_str_cstr(&log_message));
2953
3578
 
2954
3579
  cleanup:
2955
- git_buf_dispose(&log_message);
3580
+ git_str_dispose(&log_message);
2956
3581
  git_object_free(object);
2957
3582
  git_object_free(peeled);
2958
3583
  git_reference_free(current);
@@ -2965,7 +3590,7 @@ int git_repository_set_head(
2965
3590
  const char *refname)
2966
3591
  {
2967
3592
  git_reference *ref = NULL, *current = NULL, *new_head = NULL;
2968
- git_buf log_message = GIT_BUF_INIT;
3593
+ git_str log_message = GIT_STR_INIT;
2969
3594
  int error;
2970
3595
 
2971
3596
  GIT_ASSERT_ARG(repo);
@@ -2992,18 +3617,18 @@ int git_repository_set_head(
2992
3617
  if (!error) {
2993
3618
  if (git_reference_is_branch(ref)) {
2994
3619
  error = git_reference_symbolic_create(&new_head, repo, GIT_HEAD_FILE,
2995
- git_reference_name(ref), true, git_buf_cstr(&log_message));
3620
+ git_reference_name(ref), true, git_str_cstr(&log_message));
2996
3621
  } else {
2997
3622
  error = detach(repo, git_reference_target(ref),
2998
3623
  git_reference_is_tag(ref) || git_reference_is_remote(ref) ? refname : NULL);
2999
3624
  }
3000
3625
  } else if (git_reference__is_branch(refname)) {
3001
3626
  error = git_reference_symbolic_create(&new_head, repo, GIT_HEAD_FILE, refname,
3002
- true, git_buf_cstr(&log_message));
3627
+ true, git_str_cstr(&log_message));
3003
3628
  }
3004
3629
 
3005
3630
  cleanup:
3006
- git_buf_dispose(&log_message);
3631
+ git_str_dispose(&log_message);
3007
3632
  git_reference_free(current);
3008
3633
  git_reference_free(ref);
3009
3634
  git_reference_free(new_head);
@@ -3012,26 +3637,27 @@ cleanup:
3012
3637
 
3013
3638
  int git_repository_set_head_detached(
3014
3639
  git_repository *repo,
3015
- const git_oid *commitish)
3640
+ const git_oid *committish)
3016
3641
  {
3017
- return detach(repo, commitish, NULL);
3642
+ return detach(repo, committish, NULL);
3018
3643
  }
3019
3644
 
3020
3645
  int git_repository_set_head_detached_from_annotated(
3021
3646
  git_repository *repo,
3022
- const git_annotated_commit *commitish)
3647
+ const git_annotated_commit *committish)
3023
3648
  {
3024
3649
  GIT_ASSERT_ARG(repo);
3025
- GIT_ASSERT_ARG(commitish);
3650
+ GIT_ASSERT_ARG(committish);
3026
3651
 
3027
- return detach(repo, git_annotated_commit_id(commitish), commitish->description);
3652
+ return detach(repo, git_annotated_commit_id(committish), committish->description);
3028
3653
  }
3029
3654
 
3030
3655
  int git_repository_detach_head(git_repository *repo)
3031
3656
  {
3032
3657
  git_reference *old_head = NULL, *new_head = NULL, *current = NULL;
3033
3658
  git_object *object = NULL;
3034
- git_buf log_message = GIT_BUF_INIT;
3659
+ git_str log_message = GIT_STR_INIT;
3660
+ const char *idstr;
3035
3661
  int error;
3036
3662
 
3037
3663
  GIT_ASSERT_ARG(repo);
@@ -3045,14 +3671,19 @@ int git_repository_detach_head(git_repository *repo)
3045
3671
  if ((error = git_object_lookup(&object, repo, git_reference_target(old_head), GIT_OBJECT_COMMIT)) < 0)
3046
3672
  goto cleanup;
3047
3673
 
3048
- if ((error = checkout_message(&log_message, current, git_oid_tostr_s(git_object_id(object)))) < 0)
3674
+ if ((idstr = git_oid_tostr_s(git_object_id(object))) == NULL) {
3675
+ error = -1;
3676
+ goto cleanup;
3677
+ }
3678
+
3679
+ if ((error = checkout_message(&log_message, current, idstr)) < 0)
3049
3680
  goto cleanup;
3050
3681
 
3051
3682
  error = git_reference_create(&new_head, repo, GIT_HEAD_FILE, git_reference_target(old_head),
3052
- 1, git_buf_cstr(&log_message));
3683
+ 1, git_str_cstr(&log_message));
3053
3684
 
3054
3685
  cleanup:
3055
- git_buf_dispose(&log_message);
3686
+ git_str_dispose(&log_message);
3056
3687
  git_object_free(object);
3057
3688
  git_reference_free(old_head);
3058
3689
  git_reference_free(new_head);
@@ -3066,69 +3697,69 @@ cleanup:
3066
3697
  */
3067
3698
  int git_repository_state(git_repository *repo)
3068
3699
  {
3069
- git_buf repo_path = GIT_BUF_INIT;
3700
+ git_str repo_path = GIT_STR_INIT;
3070
3701
  int state = GIT_REPOSITORY_STATE_NONE;
3071
3702
 
3072
3703
  GIT_ASSERT_ARG(repo);
3073
3704
 
3074
- if (git_buf_puts(&repo_path, repo->gitdir) < 0)
3705
+ if (git_str_puts(&repo_path, repo->gitdir) < 0)
3075
3706
  return -1;
3076
3707
 
3077
- if (git_path_contains_file(&repo_path, GIT_REBASE_MERGE_INTERACTIVE_FILE))
3708
+ if (git_fs_path_contains_file(&repo_path, GIT_REBASE_MERGE_INTERACTIVE_FILE))
3078
3709
  state = GIT_REPOSITORY_STATE_REBASE_INTERACTIVE;
3079
- else if (git_path_contains_dir(&repo_path, GIT_REBASE_MERGE_DIR))
3710
+ else if (git_fs_path_contains_dir(&repo_path, GIT_REBASE_MERGE_DIR))
3080
3711
  state = GIT_REPOSITORY_STATE_REBASE_MERGE;
3081
- else if (git_path_contains_file(&repo_path, GIT_REBASE_APPLY_REBASING_FILE))
3712
+ else if (git_fs_path_contains_file(&repo_path, GIT_REBASE_APPLY_REBASING_FILE))
3082
3713
  state = GIT_REPOSITORY_STATE_REBASE;
3083
- else if (git_path_contains_file(&repo_path, GIT_REBASE_APPLY_APPLYING_FILE))
3714
+ else if (git_fs_path_contains_file(&repo_path, GIT_REBASE_APPLY_APPLYING_FILE))
3084
3715
  state = GIT_REPOSITORY_STATE_APPLY_MAILBOX;
3085
- else if (git_path_contains_dir(&repo_path, GIT_REBASE_APPLY_DIR))
3716
+ else if (git_fs_path_contains_dir(&repo_path, GIT_REBASE_APPLY_DIR))
3086
3717
  state = GIT_REPOSITORY_STATE_APPLY_MAILBOX_OR_REBASE;
3087
- else if (git_path_contains_file(&repo_path, GIT_MERGE_HEAD_FILE))
3718
+ else if (git_fs_path_contains_file(&repo_path, GIT_MERGE_HEAD_FILE))
3088
3719
  state = GIT_REPOSITORY_STATE_MERGE;
3089
- else if (git_path_contains_file(&repo_path, GIT_REVERT_HEAD_FILE)) {
3720
+ else if (git_fs_path_contains_file(&repo_path, GIT_REVERT_HEAD_FILE)) {
3090
3721
  state = GIT_REPOSITORY_STATE_REVERT;
3091
- if (git_path_contains_file(&repo_path, GIT_SEQUENCER_TODO_FILE)) {
3722
+ if (git_fs_path_contains_file(&repo_path, GIT_SEQUENCER_TODO_FILE)) {
3092
3723
  state = GIT_REPOSITORY_STATE_REVERT_SEQUENCE;
3093
3724
  }
3094
- } else if (git_path_contains_file(&repo_path, GIT_CHERRYPICK_HEAD_FILE)) {
3725
+ } else if (git_fs_path_contains_file(&repo_path, GIT_CHERRYPICK_HEAD_FILE)) {
3095
3726
  state = GIT_REPOSITORY_STATE_CHERRYPICK;
3096
- if (git_path_contains_file(&repo_path, GIT_SEQUENCER_TODO_FILE)) {
3727
+ if (git_fs_path_contains_file(&repo_path, GIT_SEQUENCER_TODO_FILE)) {
3097
3728
  state = GIT_REPOSITORY_STATE_CHERRYPICK_SEQUENCE;
3098
3729
  }
3099
- } else if (git_path_contains_file(&repo_path, GIT_BISECT_LOG_FILE))
3730
+ } else if (git_fs_path_contains_file(&repo_path, GIT_BISECT_LOG_FILE))
3100
3731
  state = GIT_REPOSITORY_STATE_BISECT;
3101
3732
 
3102
- git_buf_dispose(&repo_path);
3733
+ git_str_dispose(&repo_path);
3103
3734
  return state;
3104
3735
  }
3105
3736
 
3106
3737
  int git_repository__cleanup_files(
3107
3738
  git_repository *repo, const char *files[], size_t files_len)
3108
3739
  {
3109
- git_buf buf = GIT_BUF_INIT;
3740
+ git_str buf = GIT_STR_INIT;
3110
3741
  size_t i;
3111
3742
  int error;
3112
3743
 
3113
3744
  for (error = 0, i = 0; !error && i < files_len; ++i) {
3114
3745
  const char *path;
3115
3746
 
3116
- if (git_buf_joinpath(&buf, repo->gitdir, files[i]) < 0)
3747
+ if (git_str_joinpath(&buf, repo->gitdir, files[i]) < 0)
3117
3748
  return -1;
3118
3749
 
3119
- path = git_buf_cstr(&buf);
3750
+ path = git_str_cstr(&buf);
3120
3751
 
3121
- if (git_path_isfile(path)) {
3752
+ if (git_fs_path_isfile(path)) {
3122
3753
  error = p_unlink(path);
3123
- } else if (git_path_isdir(path)) {
3754
+ } else if (git_fs_path_isdir(path)) {
3124
3755
  error = git_futils_rmdir_r(path, NULL,
3125
3756
  GIT_RMDIR_REMOVE_FILES | GIT_RMDIR_REMOVE_BLOCKERS);
3126
3757
  }
3127
3758
 
3128
- git_buf_clear(&buf);
3759
+ git_str_clear(&buf);
3129
3760
  }
3130
3761
 
3131
- git_buf_dispose(&buf);
3762
+ git_str_dispose(&buf);
3132
3763
  return error;
3133
3764
  }
3134
3765
 
@@ -3151,17 +3782,77 @@ int git_repository_state_cleanup(git_repository *repo)
3151
3782
  return git_repository__cleanup_files(repo, state_files, ARRAY_SIZE(state_files));
3152
3783
  }
3153
3784
 
3785
+ int git_repository__shallow_roots(
3786
+ git_oid **out,
3787
+ size_t *out_len,
3788
+ git_repository *repo)
3789
+ {
3790
+ int error = 0;
3791
+
3792
+ if (!repo->shallow_grafts && (error = load_grafts(repo)) < 0)
3793
+ return error;
3794
+
3795
+ if ((error = git_grafts_refresh(repo->shallow_grafts)) < 0)
3796
+ return error;
3797
+
3798
+ if ((error = git_grafts_oids(out, out_len, repo->shallow_grafts)) < 0)
3799
+ return error;
3800
+
3801
+ return 0;
3802
+ }
3803
+
3804
+ int git_repository__shallow_roots_write(git_repository *repo, git_oidarray *roots)
3805
+ {
3806
+ git_filebuf file = GIT_FILEBUF_INIT;
3807
+ git_str path = GIT_STR_INIT;
3808
+ char oid_str[GIT_OID_MAX_HEXSIZE + 1];
3809
+ size_t i;
3810
+ int filebuf_hash, error = 0;
3811
+
3812
+ GIT_ASSERT_ARG(repo);
3813
+
3814
+ filebuf_hash = git_filebuf_hash_flags(git_oid_algorithm(repo->oid_type));
3815
+ GIT_ASSERT(filebuf_hash);
3816
+
3817
+ if ((error = git_str_joinpath(&path, repo->gitdir, "shallow")) < 0)
3818
+ goto on_error;
3819
+
3820
+ if ((error = git_filebuf_open(&file, git_str_cstr(&path), filebuf_hash, 0666)) < 0)
3821
+ goto on_error;
3822
+
3823
+ for (i = 0; i < roots->count; i++) {
3824
+ git_oid_tostr(oid_str, sizeof(oid_str), &roots->ids[i]);
3825
+ git_filebuf_write(&file, oid_str, git_oid_hexsize(repo->oid_type));
3826
+ git_filebuf_write(&file, "\n", 1);
3827
+ }
3828
+
3829
+ git_filebuf_commit(&file);
3830
+
3831
+ if ((error = load_grafts(repo)) < 0) {
3832
+ error = -1;
3833
+ goto on_error;
3834
+ }
3835
+
3836
+ if (!roots->count)
3837
+ remove(path.ptr);
3838
+
3839
+ on_error:
3840
+ git_str_dispose(&path);
3841
+
3842
+ return error;
3843
+ }
3844
+
3154
3845
  int git_repository_is_shallow(git_repository *repo)
3155
3846
  {
3156
- git_buf path = GIT_BUF_INIT;
3847
+ git_str path = GIT_STR_INIT;
3157
3848
  struct stat st;
3158
3849
  int error;
3159
3850
 
3160
- if ((error = git_buf_joinpath(&path, repo->gitdir, "shallow")) < 0)
3851
+ if ((error = git_str_joinpath(&path, repo->gitdir, "shallow")) < 0)
3161
3852
  return error;
3162
3853
 
3163
- error = git_path_lstat(path.ptr, &st);
3164
- git_buf_dispose(&path);
3854
+ error = git_fs_path_lstat(path.ptr, &st);
3855
+ git_str_dispose(&path);
3165
3856
 
3166
3857
  if (error == GIT_ENOTFOUND) {
3167
3858
  git_error_clear();
@@ -3170,6 +3861,7 @@ int git_repository_is_shallow(git_repository *repo)
3170
3861
 
3171
3862
  if (error < 0)
3172
3863
  return error;
3864
+
3173
3865
  return st.st_size == 0 ? 0 : 1;
3174
3866
  }
3175
3867
 
@@ -3236,3 +3928,94 @@ int git_repository_submodule_cache_clear(git_repository *repo)
3236
3928
  repo->submodule_cache = NULL;
3237
3929
  return error;
3238
3930
  }
3931
+
3932
+ git_oid_t git_repository_oid_type(git_repository *repo)
3933
+ {
3934
+ return repo ? repo->oid_type : 0;
3935
+ }
3936
+
3937
+ struct mergehead_data {
3938
+ git_repository *repo;
3939
+ git_vector *parents;
3940
+ };
3941
+
3942
+ static int insert_mergehead(const git_oid *oid, void *payload)
3943
+ {
3944
+ git_commit *commit;
3945
+ struct mergehead_data *data = (struct mergehead_data *)payload;
3946
+
3947
+ if (git_commit_lookup(&commit, data->repo, oid) < 0)
3948
+ return -1;
3949
+
3950
+ return git_vector_insert(data->parents, commit);
3951
+ }
3952
+
3953
+ int git_repository_commit_parents(git_commitarray *out, git_repository *repo)
3954
+ {
3955
+ git_commit *first_parent = NULL, *commit;
3956
+ git_reference *head_ref = NULL;
3957
+ git_vector parents = GIT_VECTOR_INIT;
3958
+ struct mergehead_data data;
3959
+ size_t i;
3960
+ int error;
3961
+
3962
+ GIT_ASSERT_ARG(out && repo);
3963
+
3964
+ out->count = 0;
3965
+ out->commits = NULL;
3966
+
3967
+ error = git_revparse_ext((git_object **)&first_parent, &head_ref, repo, "HEAD");
3968
+
3969
+ if (error != 0) {
3970
+ if (error == GIT_ENOTFOUND)
3971
+ error = 0;
3972
+
3973
+ goto done;
3974
+ }
3975
+
3976
+ if ((error = git_vector_insert(&parents, first_parent)) < 0)
3977
+ goto done;
3978
+
3979
+ data.repo = repo;
3980
+ data.parents = &parents;
3981
+
3982
+ error = git_repository_mergehead_foreach(repo, insert_mergehead, &data);
3983
+
3984
+ if (error == GIT_ENOTFOUND)
3985
+ error = 0;
3986
+ else if (error != 0)
3987
+ goto done;
3988
+
3989
+ out->commits = (git_commit **)git_vector_detach(&out->count, NULL, &parents);
3990
+
3991
+ done:
3992
+ git_vector_foreach(&parents, i, commit)
3993
+ git__free(commit);
3994
+
3995
+ git_reference_free(head_ref);
3996
+ return error;
3997
+ }
3998
+
3999
+ int git_repository__abbrev_length(int *out, git_repository *repo)
4000
+ {
4001
+ size_t oid_hexsize;
4002
+ int len;
4003
+ int error;
4004
+
4005
+ oid_hexsize = git_oid_hexsize(repo->oid_type);
4006
+
4007
+ if ((error = git_repository__configmap_lookup(&len, repo, GIT_CONFIGMAP_ABBREV)) < 0)
4008
+ return error;
4009
+
4010
+ if (len < GIT_ABBREV_MINIMUM) {
4011
+ git_error_set(GIT_ERROR_CONFIG, "invalid oid abbreviation setting: '%d'", len);
4012
+ return -1;
4013
+ }
4014
+
4015
+ if (len == GIT_ABBREV_FALSE || (size_t)len > oid_hexsize)
4016
+ len = (int)oid_hexsize;
4017
+
4018
+ *out = len;
4019
+
4020
+ return error;
4021
+ }