rugged 1.6.3 → 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 (443) hide show
  1. checksums.yaml +4 -4
  2. data/ext/rugged/rugged_allocator.c +0 -54
  3. data/lib/rugged/version.rb +1 -1
  4. data/vendor/libgit2/AUTHORS +1 -0
  5. data/vendor/libgit2/CMakeLists.txt +25 -17
  6. data/vendor/libgit2/COPYING +195 -1
  7. data/vendor/libgit2/cmake/CheckPrototypeDefinitionSafe.cmake +16 -0
  8. data/vendor/libgit2/cmake/{FindIconv.cmake → FindIntlIconv.cmake} +6 -0
  9. data/vendor/libgit2/cmake/FindLLHTTP.cmake +39 -0
  10. data/vendor/libgit2/cmake/SelectGSSAPI.cmake +4 -4
  11. data/vendor/libgit2/cmake/SelectHTTPParser.cmake +23 -8
  12. data/vendor/libgit2/cmake/SelectHTTPSBackend.cmake +34 -6
  13. data/vendor/libgit2/cmake/SelectHashes.cmake +32 -11
  14. data/vendor/libgit2/cmake/SelectRegex.cmake +6 -1
  15. data/vendor/libgit2/cmake/SelectSSH.cmake +22 -17
  16. data/vendor/libgit2/cmake/SelectXdiff.cmake +9 -0
  17. data/vendor/libgit2/cmake/SelectZlib.cmake +4 -0
  18. data/vendor/libgit2/deps/llhttp/CMakeLists.txt +8 -0
  19. data/vendor/libgit2/deps/llhttp/LICENSE-MIT +22 -0
  20. data/vendor/libgit2/deps/llhttp/api.c +510 -0
  21. data/vendor/libgit2/deps/llhttp/http.c +170 -0
  22. data/vendor/libgit2/deps/llhttp/llhttp.c +10168 -0
  23. data/vendor/libgit2/deps/llhttp/llhttp.h +897 -0
  24. data/vendor/libgit2/deps/ntlmclient/CMakeLists.txt +1 -1
  25. data/vendor/libgit2/deps/ntlmclient/crypt_builtin_md4.c +311 -0
  26. data/vendor/libgit2/deps/ntlmclient/crypt_commoncrypto.c +2 -1
  27. data/vendor/libgit2/deps/ntlmclient/crypt_mbedtls.c +0 -20
  28. data/vendor/libgit2/deps/ntlmclient/crypt_openssl.c +4 -4
  29. data/vendor/libgit2/deps/ntlmclient/ntlm.c +21 -21
  30. data/vendor/libgit2/deps/ntlmclient/unicode_builtin.c +5 -4
  31. data/vendor/libgit2/deps/ntlmclient/unicode_iconv.c +2 -1
  32. data/vendor/libgit2/deps/ntlmclient/utf8.h +1176 -721
  33. data/vendor/libgit2/deps/ntlmclient/util.h +11 -0
  34. data/vendor/libgit2/deps/pcre/CMakeLists.txt +1 -0
  35. data/vendor/libgit2/deps/pcre/LICENCE +5 -5
  36. data/vendor/libgit2/deps/pcre/pcre.h +2 -2
  37. data/vendor/libgit2/deps/pcre/pcre_compile.c +6 -3
  38. data/vendor/libgit2/deps/pcre/pcre_exec.c +2 -2
  39. data/vendor/libgit2/deps/xdiff/CMakeLists.txt +28 -0
  40. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/git-xdiff.h +4 -1
  41. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xdiffi.c +19 -18
  42. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xdiffi.h +2 -4
  43. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xemit.c +3 -3
  44. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xhistogram.c +7 -18
  45. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xmacros.h +18 -1
  46. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xmerge.c +22 -20
  47. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xpatience.c +21 -30
  48. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xprepare.c +13 -30
  49. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xutils.c +18 -1
  50. data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xutils.h +2 -1
  51. data/vendor/libgit2/deps/zlib/CMakeLists.txt +6 -1
  52. data/vendor/libgit2/deps/zlib/LICENSE +22 -0
  53. data/vendor/libgit2/deps/zlib/adler32.c +5 -27
  54. data/vendor/libgit2/deps/zlib/crc32.c +94 -167
  55. data/vendor/libgit2/deps/zlib/deflate.c +358 -435
  56. data/vendor/libgit2/deps/zlib/deflate.h +41 -10
  57. data/vendor/libgit2/deps/zlib/gzguts.h +13 -18
  58. data/vendor/libgit2/deps/zlib/infback.c +17 -30
  59. data/vendor/libgit2/deps/zlib/inffast.c +1 -4
  60. data/vendor/libgit2/deps/zlib/inffast.h +1 -1
  61. data/vendor/libgit2/deps/zlib/inflate.c +36 -102
  62. data/vendor/libgit2/deps/zlib/inftrees.c +6 -11
  63. data/vendor/libgit2/deps/zlib/inftrees.h +6 -6
  64. data/vendor/libgit2/deps/zlib/trees.c +287 -352
  65. data/vendor/libgit2/deps/zlib/zconf.h +23 -14
  66. data/vendor/libgit2/deps/zlib/zlib.h +202 -202
  67. data/vendor/libgit2/deps/zlib/zutil.c +18 -44
  68. data/vendor/libgit2/deps/zlib/zutil.h +13 -33
  69. data/vendor/libgit2/include/git2/annotated_commit.h +12 -5
  70. data/vendor/libgit2/include/git2/apply.h +27 -6
  71. data/vendor/libgit2/include/git2/attr.h +17 -4
  72. data/vendor/libgit2/include/git2/blame.h +133 -28
  73. data/vendor/libgit2/include/git2/blob.h +71 -28
  74. data/vendor/libgit2/include/git2/branch.h +22 -15
  75. data/vendor/libgit2/include/git2/buffer.h +6 -4
  76. data/vendor/libgit2/include/git2/cert.h +2 -1
  77. data/vendor/libgit2/include/git2/checkout.h +83 -32
  78. data/vendor/libgit2/include/git2/cherrypick.h +10 -3
  79. data/vendor/libgit2/include/git2/clone.h +25 -9
  80. data/vendor/libgit2/include/git2/commit.h +132 -3
  81. data/vendor/libgit2/include/git2/common.h +138 -56
  82. data/vendor/libgit2/include/git2/config.h +93 -23
  83. data/vendor/libgit2/include/git2/credential.h +30 -2
  84. data/vendor/libgit2/include/git2/credential_helpers.h +1 -0
  85. data/vendor/libgit2/include/git2/deprecated.h +133 -3
  86. data/vendor/libgit2/include/git2/describe.h +13 -1
  87. data/vendor/libgit2/include/git2/diff.h +77 -9
  88. data/vendor/libgit2/include/git2/email.h +9 -29
  89. data/vendor/libgit2/include/git2/errors.h +49 -74
  90. data/vendor/libgit2/include/git2/filter.h +14 -7
  91. data/vendor/libgit2/include/git2/global.h +8 -1
  92. data/vendor/libgit2/include/git2/graph.h +3 -2
  93. data/vendor/libgit2/include/git2/ignore.h +10 -0
  94. data/vendor/libgit2/include/git2/index.h +100 -6
  95. data/vendor/libgit2/include/git2/indexer.h +21 -4
  96. data/vendor/libgit2/include/git2/mailmap.h +7 -1
  97. data/vendor/libgit2/include/git2/merge.h +46 -1
  98. data/vendor/libgit2/include/git2/message.h +2 -2
  99. data/vendor/libgit2/include/git2/net.h +3 -1
  100. data/vendor/libgit2/include/git2/notes.h +9 -6
  101. data/vendor/libgit2/include/git2/object.h +9 -8
  102. data/vendor/libgit2/include/git2/odb.h +91 -49
  103. data/vendor/libgit2/include/git2/odb_backend.h +80 -52
  104. data/vendor/libgit2/include/git2/oid.h +24 -25
  105. data/vendor/libgit2/include/git2/oidarray.h +7 -1
  106. data/vendor/libgit2/include/git2/pack.h +13 -1
  107. data/vendor/libgit2/include/git2/patch.h +2 -3
  108. data/vendor/libgit2/include/git2/pathspec.h +9 -0
  109. data/vendor/libgit2/include/git2/proxy.h +10 -0
  110. data/vendor/libgit2/include/git2/rebase.h +9 -6
  111. data/vendor/libgit2/include/git2/refdb.h +2 -2
  112. data/vendor/libgit2/include/git2/reflog.h +3 -2
  113. data/vendor/libgit2/include/git2/refs.h +9 -6
  114. data/vendor/libgit2/include/git2/refspec.h +14 -4
  115. data/vendor/libgit2/include/git2/remote.h +112 -18
  116. data/vendor/libgit2/include/git2/repository.h +61 -15
  117. data/vendor/libgit2/include/git2/reset.h +16 -3
  118. data/vendor/libgit2/include/git2/revert.h +9 -4
  119. data/vendor/libgit2/include/git2/revparse.h +3 -3
  120. data/vendor/libgit2/include/git2/revwalk.h +3 -2
  121. data/vendor/libgit2/include/git2/signature.h +46 -1
  122. data/vendor/libgit2/include/git2/stash.h +17 -3
  123. data/vendor/libgit2/include/git2/status.h +10 -6
  124. data/vendor/libgit2/include/git2/stdint.h +87 -85
  125. data/vendor/libgit2/include/git2/strarray.h +2 -3
  126. data/vendor/libgit2/include/git2/submodule.h +20 -9
  127. data/vendor/libgit2/include/git2/sys/alloc.h +12 -34
  128. data/vendor/libgit2/include/git2/sys/commit.h +77 -3
  129. data/vendor/libgit2/include/git2/sys/commit_graph.h +109 -58
  130. data/vendor/libgit2/include/git2/sys/config.h +80 -4
  131. data/vendor/libgit2/include/git2/sys/credential.h +4 -3
  132. data/vendor/libgit2/include/git2/sys/diff.h +21 -1
  133. data/vendor/libgit2/include/git2/sys/email.h +7 -0
  134. data/vendor/libgit2/include/git2/sys/errors.h +76 -0
  135. data/vendor/libgit2/include/git2/sys/filter.h +66 -3
  136. data/vendor/libgit2/include/git2/sys/hashsig.h +11 -0
  137. data/vendor/libgit2/include/git2/sys/index.h +3 -2
  138. data/vendor/libgit2/include/git2/sys/mempack.h +32 -2
  139. data/vendor/libgit2/include/git2/sys/merge.h +55 -7
  140. data/vendor/libgit2/include/git2/sys/midx.h +47 -4
  141. data/vendor/libgit2/include/git2/sys/odb_backend.h +7 -3
  142. data/vendor/libgit2/include/git2/sys/openssl.h +8 -1
  143. data/vendor/libgit2/include/git2/sys/path.h +12 -1
  144. data/vendor/libgit2/include/git2/sys/refdb_backend.h +40 -36
  145. data/vendor/libgit2/include/git2/sys/refs.h +3 -2
  146. data/vendor/libgit2/include/git2/sys/remote.h +8 -1
  147. data/vendor/libgit2/include/git2/sys/repository.h +63 -3
  148. data/vendor/libgit2/include/git2/sys/stream.h +25 -2
  149. data/vendor/libgit2/include/git2/sys/transport.h +44 -5
  150. data/vendor/libgit2/include/git2/tag.h +3 -1
  151. data/vendor/libgit2/include/git2/trace.h +9 -3
  152. data/vendor/libgit2/include/git2/transaction.h +3 -2
  153. data/vendor/libgit2/include/git2/transport.h +11 -3
  154. data/vendor/libgit2/include/git2/tree.h +16 -5
  155. data/vendor/libgit2/include/git2/types.h +19 -3
  156. data/vendor/libgit2/include/git2/version.h +44 -8
  157. data/vendor/libgit2/include/git2/worktree.h +19 -7
  158. data/vendor/libgit2/src/CMakeLists.txt +40 -15
  159. data/vendor/libgit2/src/cli/CMakeLists.txt +2 -2
  160. data/vendor/libgit2/src/cli/cmd.c +1 -1
  161. data/vendor/libgit2/src/cli/cmd.h +4 -0
  162. data/vendor/libgit2/src/cli/cmd_blame.c +287 -0
  163. data/vendor/libgit2/src/cli/cmd_cat_file.c +6 -8
  164. data/vendor/libgit2/src/cli/cmd_clone.c +27 -13
  165. data/vendor/libgit2/src/cli/cmd_config.c +241 -0
  166. data/vendor/libgit2/src/cli/cmd_hash_object.c +6 -8
  167. data/vendor/libgit2/src/cli/cmd_help.c +6 -7
  168. data/vendor/libgit2/src/cli/cmd_index_pack.c +114 -0
  169. data/vendor/libgit2/src/cli/cmd_init.c +102 -0
  170. data/vendor/libgit2/src/cli/common.c +168 -0
  171. data/vendor/libgit2/src/cli/common.h +63 -0
  172. data/vendor/libgit2/src/cli/error.h +1 -1
  173. data/vendor/libgit2/src/cli/main.c +52 -24
  174. data/vendor/libgit2/src/cli/opt.c +29 -3
  175. data/vendor/libgit2/src/cli/opt.h +21 -3
  176. data/vendor/libgit2/src/cli/opt_usage.c +102 -33
  177. data/vendor/libgit2/src/cli/opt_usage.h +6 -1
  178. data/vendor/libgit2/src/cli/progress.c +60 -10
  179. data/vendor/libgit2/src/cli/progress.h +16 -4
  180. data/vendor/libgit2/src/cli/unix/sighandler.c +2 -1
  181. data/vendor/libgit2/src/cli/win32/precompiled.h +1 -1
  182. data/vendor/libgit2/src/cli/win32/sighandler.c +1 -1
  183. data/vendor/libgit2/src/libgit2/CMakeLists.txt +27 -27
  184. data/vendor/libgit2/src/libgit2/annotated_commit.c +2 -2
  185. data/vendor/libgit2/src/libgit2/annotated_commit.h +1 -1
  186. data/vendor/libgit2/src/libgit2/apply.c +14 -16
  187. data/vendor/libgit2/src/libgit2/attr.c +30 -13
  188. data/vendor/libgit2/src/libgit2/attr_file.c +7 -2
  189. data/vendor/libgit2/src/libgit2/attr_file.h +2 -0
  190. data/vendor/libgit2/src/libgit2/attrcache.c +69 -33
  191. data/vendor/libgit2/src/libgit2/attrcache.h +5 -9
  192. data/vendor/libgit2/src/libgit2/blame.c +152 -59
  193. data/vendor/libgit2/src/libgit2/blame.h +1 -0
  194. data/vendor/libgit2/src/libgit2/blame_git.c +0 -1
  195. data/vendor/libgit2/src/libgit2/branch.c +2 -2
  196. data/vendor/libgit2/src/libgit2/cache.c +22 -17
  197. data/vendor/libgit2/src/libgit2/cache.h +7 -9
  198. data/vendor/libgit2/src/libgit2/checkout.c +34 -24
  199. data/vendor/libgit2/src/libgit2/checkout.h +0 -2
  200. data/vendor/libgit2/src/libgit2/cherrypick.c +4 -5
  201. data/vendor/libgit2/src/libgit2/clone.c +186 -164
  202. data/vendor/libgit2/src/libgit2/clone.h +4 -1
  203. data/vendor/libgit2/src/libgit2/commit.c +123 -9
  204. data/vendor/libgit2/src/libgit2/commit_graph.c +166 -88
  205. data/vendor/libgit2/src/libgit2/commit_graph.h +21 -6
  206. data/vendor/libgit2/src/libgit2/commit_list.c +12 -5
  207. data/vendor/libgit2/src/libgit2/commit_list.h +1 -0
  208. data/vendor/libgit2/src/libgit2/config.c +394 -300
  209. data/vendor/libgit2/src/libgit2/config.cmake.in +3 -0
  210. data/vendor/libgit2/src/libgit2/config.h +9 -4
  211. data/vendor/libgit2/src/libgit2/config_backend.h +8 -10
  212. data/vendor/libgit2/src/libgit2/config_cache.c +4 -5
  213. data/vendor/libgit2/src/libgit2/config_file.c +113 -96
  214. data/vendor/libgit2/src/libgit2/config_list.c +285 -0
  215. data/vendor/libgit2/src/libgit2/config_list.h +32 -0
  216. data/vendor/libgit2/src/libgit2/config_mem.c +194 -40
  217. data/vendor/libgit2/src/libgit2/config_parse.c +10 -9
  218. data/vendor/libgit2/src/libgit2/config_snapshot.c +24 -31
  219. data/vendor/libgit2/src/libgit2/describe.c +34 -31
  220. data/vendor/libgit2/src/libgit2/diff.c +17 -8
  221. data/vendor/libgit2/src/libgit2/diff.h +6 -6
  222. data/vendor/libgit2/src/libgit2/diff_driver.c +12 -19
  223. data/vendor/libgit2/src/libgit2/diff_driver.h +2 -2
  224. data/vendor/libgit2/src/libgit2/diff_file.c +7 -7
  225. data/vendor/libgit2/src/libgit2/diff_generate.c +39 -18
  226. data/vendor/libgit2/src/libgit2/diff_parse.c +22 -6
  227. data/vendor/libgit2/src/libgit2/diff_print.c +88 -13
  228. data/vendor/libgit2/src/libgit2/diff_tform.c +40 -12
  229. data/vendor/libgit2/src/libgit2/diff_xdiff.h +1 -1
  230. data/vendor/libgit2/src/libgit2/email.c +5 -3
  231. data/vendor/libgit2/src/libgit2/fetch.c +39 -9
  232. data/vendor/libgit2/src/libgit2/fetch.h +0 -2
  233. data/vendor/libgit2/src/libgit2/fetchhead.c +11 -9
  234. data/vendor/libgit2/src/libgit2/filter.c +5 -5
  235. data/vendor/libgit2/src/libgit2/git2.rc +3 -3
  236. data/vendor/libgit2/src/libgit2/grafts.c +270 -0
  237. data/vendor/libgit2/src/libgit2/grafts.h +35 -0
  238. data/vendor/libgit2/src/libgit2/graph.c +1 -1
  239. data/vendor/libgit2/src/libgit2/hashmap_oid.h +30 -0
  240. data/vendor/libgit2/src/libgit2/ident.c +3 -3
  241. data/vendor/libgit2/src/libgit2/ignore.c +9 -5
  242. data/vendor/libgit2/src/libgit2/index.c +392 -208
  243. data/vendor/libgit2/src/libgit2/index.h +16 -3
  244. data/vendor/libgit2/src/libgit2/index_map.c +95 -0
  245. data/vendor/libgit2/src/libgit2/index_map.h +28 -0
  246. data/vendor/libgit2/src/libgit2/indexer.c +44 -41
  247. data/vendor/libgit2/src/libgit2/iterator.c +34 -13
  248. data/vendor/libgit2/src/libgit2/iterator.h +3 -0
  249. data/vendor/libgit2/src/libgit2/libgit2.c +155 -331
  250. data/vendor/libgit2/src/libgit2/mailmap.c +1 -1
  251. data/vendor/libgit2/src/libgit2/merge.c +56 -46
  252. data/vendor/libgit2/src/libgit2/merge_driver.c +2 -2
  253. data/vendor/libgit2/src/libgit2/merge_file.c +0 -2
  254. data/vendor/libgit2/src/libgit2/midx.c +86 -44
  255. data/vendor/libgit2/src/libgit2/midx.h +13 -3
  256. data/vendor/libgit2/src/libgit2/mwindow.c +38 -45
  257. data/vendor/libgit2/src/libgit2/mwindow.h +4 -0
  258. data/vendor/libgit2/src/libgit2/notes.c +9 -8
  259. data/vendor/libgit2/src/libgit2/object.c +42 -16
  260. data/vendor/libgit2/src/libgit2/object.h +6 -0
  261. data/vendor/libgit2/src/libgit2/odb.c +16 -9
  262. data/vendor/libgit2/src/libgit2/odb_mempack.c +49 -17
  263. data/vendor/libgit2/src/libgit2/odb_pack.c +28 -7
  264. data/vendor/libgit2/src/libgit2/oid.c +35 -2
  265. data/vendor/libgit2/src/libgit2/oid.h +11 -0
  266. data/vendor/libgit2/src/libgit2/oidarray.c +49 -3
  267. data/vendor/libgit2/src/libgit2/oidarray.h +5 -1
  268. data/vendor/libgit2/src/libgit2/pack-objects.c +77 -43
  269. data/vendor/libgit2/src/libgit2/pack-objects.h +17 -6
  270. data/vendor/libgit2/src/libgit2/pack.c +33 -27
  271. data/vendor/libgit2/src/libgit2/pack.h +15 -10
  272. data/vendor/libgit2/src/libgit2/parse.c +7 -4
  273. data/vendor/libgit2/src/libgit2/parse.h +1 -1
  274. data/vendor/libgit2/src/libgit2/patch.h +7 -1
  275. data/vendor/libgit2/src/libgit2/patch_generate.c +24 -5
  276. data/vendor/libgit2/src/libgit2/patch_parse.c +18 -10
  277. data/vendor/libgit2/src/libgit2/path.c +1 -1
  278. data/vendor/libgit2/src/libgit2/pathspec.c +1 -1
  279. data/vendor/libgit2/src/libgit2/push.c +81 -30
  280. data/vendor/libgit2/src/libgit2/push.h +1 -0
  281. data/vendor/libgit2/src/libgit2/reader.c +1 -1
  282. data/vendor/libgit2/src/libgit2/rebase.c +72 -84
  283. data/vendor/libgit2/src/libgit2/refdb_fs.c +146 -70
  284. data/vendor/libgit2/src/libgit2/reflog.c +1 -2
  285. data/vendor/libgit2/src/libgit2/reflog.h +2 -0
  286. data/vendor/libgit2/src/libgit2/refs.c +34 -8
  287. data/vendor/libgit2/src/libgit2/refs.h +6 -1
  288. data/vendor/libgit2/src/libgit2/refspec.c +28 -1
  289. data/vendor/libgit2/src/libgit2/refspec.h +8 -0
  290. data/vendor/libgit2/src/libgit2/remote.c +136 -67
  291. data/vendor/libgit2/src/libgit2/remote.h +1 -0
  292. data/vendor/libgit2/src/libgit2/repository.c +789 -330
  293. data/vendor/libgit2/src/libgit2/repository.h +22 -3
  294. data/vendor/libgit2/src/libgit2/reset.c +2 -2
  295. data/vendor/libgit2/src/libgit2/revert.c +9 -13
  296. data/vendor/libgit2/src/libgit2/revparse.c +6 -3
  297. data/vendor/libgit2/src/libgit2/revwalk.c +36 -11
  298. data/vendor/libgit2/src/libgit2/revwalk.h +3 -3
  299. data/vendor/libgit2/src/libgit2/settings.c +468 -0
  300. data/vendor/libgit2/src/libgit2/settings.h +6 -2
  301. data/vendor/libgit2/src/libgit2/signature.c +132 -15
  302. data/vendor/libgit2/src/libgit2/signature.h +0 -1
  303. data/vendor/libgit2/src/libgit2/stash.c +9 -8
  304. data/vendor/libgit2/src/libgit2/status.c +1 -1
  305. data/vendor/libgit2/src/libgit2/streams/mbedtls.c +54 -61
  306. data/vendor/libgit2/src/libgit2/streams/openssl.c +40 -23
  307. data/vendor/libgit2/src/libgit2/streams/openssl.h +2 -0
  308. data/vendor/libgit2/src/libgit2/streams/openssl_dynamic.c +4 -0
  309. data/vendor/libgit2/src/libgit2/streams/openssl_dynamic.h +3 -0
  310. data/vendor/libgit2/src/libgit2/streams/schannel.c +715 -0
  311. data/vendor/libgit2/src/libgit2/streams/schannel.h +28 -0
  312. data/vendor/libgit2/src/libgit2/streams/socket.c +237 -51
  313. data/vendor/libgit2/src/libgit2/streams/socket.h +3 -1
  314. data/vendor/libgit2/src/libgit2/streams/stransport.c +79 -19
  315. data/vendor/libgit2/src/libgit2/streams/tls.c +5 -0
  316. data/vendor/libgit2/src/libgit2/submodule.c +106 -63
  317. data/vendor/libgit2/src/libgit2/submodule.h +9 -10
  318. data/vendor/libgit2/src/libgit2/tag.c +1 -1
  319. data/vendor/libgit2/src/libgit2/trailer.c +6 -6
  320. data/vendor/libgit2/src/libgit2/transaction.c +26 -20
  321. data/vendor/libgit2/src/libgit2/transaction.h +4 -1
  322. data/vendor/libgit2/src/libgit2/transport.c +4 -1
  323. data/vendor/libgit2/src/libgit2/transports/auth.h +1 -2
  324. data/vendor/libgit2/src/libgit2/transports/{auth_negotiate.c → auth_gssapi.c} +32 -32
  325. data/vendor/libgit2/src/libgit2/transports/auth_negotiate.h +1 -1
  326. data/vendor/libgit2/src/libgit2/transports/auth_ntlm.h +1 -1
  327. data/vendor/libgit2/src/libgit2/transports/{auth_ntlm.c → auth_ntlmclient.c} +12 -12
  328. data/vendor/libgit2/src/libgit2/transports/auth_sspi.c +341 -0
  329. data/vendor/libgit2/src/libgit2/transports/credential.c +1 -1
  330. data/vendor/libgit2/src/libgit2/transports/git.c +7 -8
  331. data/vendor/libgit2/src/libgit2/transports/http.c +8 -4
  332. data/vendor/libgit2/src/libgit2/transports/http.h +0 -10
  333. data/vendor/libgit2/src/libgit2/transports/httpclient.c +117 -72
  334. data/vendor/libgit2/src/libgit2/transports/httpparser.c +128 -0
  335. data/vendor/libgit2/src/libgit2/transports/httpparser.h +99 -0
  336. data/vendor/libgit2/src/libgit2/transports/local.c +21 -11
  337. data/vendor/libgit2/src/libgit2/transports/smart.c +50 -32
  338. data/vendor/libgit2/src/libgit2/transports/smart.h +26 -9
  339. data/vendor/libgit2/src/libgit2/transports/smart_pkt.c +139 -18
  340. data/vendor/libgit2/src/libgit2/transports/smart_protocol.c +209 -57
  341. data/vendor/libgit2/src/libgit2/transports/ssh.c +41 -1103
  342. data/vendor/libgit2/src/libgit2/transports/ssh_exec.c +347 -0
  343. data/vendor/libgit2/src/libgit2/transports/ssh_exec.h +26 -0
  344. data/vendor/libgit2/src/libgit2/transports/ssh_libssh2.c +1126 -0
  345. data/vendor/libgit2/src/libgit2/transports/ssh_libssh2.h +28 -0
  346. data/vendor/libgit2/src/libgit2/transports/winhttp.c +48 -21
  347. data/vendor/libgit2/src/libgit2/tree-cache.c +26 -16
  348. data/vendor/libgit2/src/libgit2/tree-cache.h +5 -3
  349. data/vendor/libgit2/src/libgit2/tree.c +35 -27
  350. data/vendor/libgit2/src/libgit2/tree.h +3 -2
  351. data/vendor/libgit2/src/libgit2/worktree.c +39 -27
  352. data/vendor/libgit2/src/util/CMakeLists.txt +4 -6
  353. data/vendor/libgit2/src/util/alloc.c +69 -7
  354. data/vendor/libgit2/src/util/alloc.h +34 -9
  355. data/vendor/libgit2/src/util/allocators/debugalloc.c +73 -0
  356. data/vendor/libgit2/src/{cli/cli.h → util/allocators/debugalloc.h} +6 -9
  357. data/vendor/libgit2/src/util/allocators/failalloc.c +0 -60
  358. data/vendor/libgit2/src/util/allocators/failalloc.h +0 -6
  359. data/vendor/libgit2/src/util/allocators/stdalloc.c +2 -115
  360. data/vendor/libgit2/src/util/allocators/win32_leakcheck.c +0 -68
  361. data/vendor/libgit2/src/util/array.h +24 -18
  362. data/vendor/libgit2/src/util/cc-compat.h +4 -0
  363. data/vendor/libgit2/src/util/ctype_compat.h +70 -0
  364. data/vendor/libgit2/src/util/date.c +22 -14
  365. data/vendor/libgit2/src/util/date.h +12 -0
  366. data/vendor/libgit2/src/util/errors.c +401 -0
  367. data/vendor/libgit2/src/{libgit2 → util}/errors.h +21 -17
  368. data/vendor/libgit2/src/util/filebuf.c +6 -1
  369. data/vendor/libgit2/src/util/filebuf.h +19 -6
  370. data/vendor/libgit2/src/util/fs_path.c +16 -5
  371. data/vendor/libgit2/src/util/fs_path.h +23 -0
  372. data/vendor/libgit2/src/util/futils.c +14 -10
  373. data/vendor/libgit2/src/util/futils.h +13 -4
  374. data/vendor/libgit2/src/util/git2_features.h.in +21 -4
  375. data/vendor/libgit2/src/util/git2_util.h +6 -0
  376. data/vendor/libgit2/src/util/hash/openssl.c +152 -0
  377. data/vendor/libgit2/src/util/hash/openssl.h +17 -1
  378. data/vendor/libgit2/src/util/hash/sha.h +4 -1
  379. data/vendor/libgit2/src/util/hashmap.h +424 -0
  380. data/vendor/libgit2/src/util/hashmap_str.h +43 -0
  381. data/vendor/libgit2/src/util/integer.h +3 -1
  382. data/vendor/libgit2/src/util/net.c +318 -161
  383. data/vendor/libgit2/src/util/net.h +27 -0
  384. data/vendor/libgit2/src/util/pool.c +1 -1
  385. data/vendor/libgit2/src/util/pool.h +5 -0
  386. data/vendor/libgit2/src/util/posix.c +54 -0
  387. data/vendor/libgit2/src/util/posix.h +22 -0
  388. data/vendor/libgit2/src/util/pqueue.h +1 -1
  389. data/vendor/libgit2/src/util/process.h +222 -0
  390. data/vendor/libgit2/src/util/rand.c +6 -10
  391. data/vendor/libgit2/src/util/regexp.c +1 -1
  392. data/vendor/libgit2/src/util/sortedcache.c +14 -13
  393. data/vendor/libgit2/src/util/sortedcache.h +3 -3
  394. data/vendor/libgit2/src/util/staticstr.h +66 -0
  395. data/vendor/libgit2/src/util/str.c +2 -2
  396. data/vendor/libgit2/src/util/strlist.c +108 -0
  397. data/vendor/libgit2/src/util/strlist.h +36 -0
  398. data/vendor/libgit2/src/util/unix/posix.h +0 -2
  399. data/vendor/libgit2/src/util/unix/process.c +629 -0
  400. data/vendor/libgit2/src/util/unix/realpath.c +23 -5
  401. data/vendor/libgit2/src/util/util.c +17 -12
  402. data/vendor/libgit2/src/util/util.h +28 -54
  403. data/vendor/libgit2/src/util/vector.c +3 -3
  404. data/vendor/libgit2/src/util/vector.h +2 -2
  405. data/vendor/libgit2/src/util/win32/error.c +1 -1
  406. data/vendor/libgit2/src/util/win32/path_w32.c +8 -8
  407. data/vendor/libgit2/src/util/win32/posix_w32.c +30 -7
  408. data/vendor/libgit2/src/util/win32/process.c +506 -0
  409. data/vendor/libgit2/src/util/win32/utf-conv.c +73 -75
  410. data/vendor/libgit2/src/util/win32/utf-conv.h +81 -14
  411. data/vendor/libgit2/src/util/win32/w32_util.c +1 -1
  412. metadata +72 -49
  413. data/vendor/libgit2/cmake/SelectWinHTTP.cmake +0 -17
  414. data/vendor/libgit2/deps/http-parser/CMakeLists.txt +0 -6
  415. data/vendor/libgit2/deps/http-parser/COPYING +0 -23
  416. data/vendor/libgit2/deps/http-parser/http_parser.c +0 -2182
  417. data/vendor/libgit2/deps/http-parser/http_parser.h +0 -305
  418. data/vendor/libgit2/deps/zlib/COPYING +0 -27
  419. data/vendor/libgit2/include/git2/sys/reflog.h +0 -21
  420. data/vendor/libgit2/src/libgit2/config_entries.c +0 -237
  421. data/vendor/libgit2/src/libgit2/config_entries.h +0 -24
  422. data/vendor/libgit2/src/libgit2/errors.c +0 -238
  423. data/vendor/libgit2/src/libgit2/idxmap.c +0 -157
  424. data/vendor/libgit2/src/libgit2/idxmap.h +0 -177
  425. data/vendor/libgit2/src/libgit2/libgit2.h +0 -15
  426. data/vendor/libgit2/src/libgit2/netops.c +0 -124
  427. data/vendor/libgit2/src/libgit2/netops.h +0 -68
  428. data/vendor/libgit2/src/libgit2/offmap.c +0 -101
  429. data/vendor/libgit2/src/libgit2/offmap.h +0 -133
  430. data/vendor/libgit2/src/libgit2/oidmap.c +0 -107
  431. data/vendor/libgit2/src/libgit2/oidmap.h +0 -128
  432. data/vendor/libgit2/src/libgit2/threadstate.c +0 -84
  433. data/vendor/libgit2/src/libgit2/threadstate.h +0 -24
  434. data/vendor/libgit2/src/libgit2/transports/ssh.h +0 -14
  435. data/vendor/libgit2/src/util/khash.h +0 -615
  436. data/vendor/libgit2/src/util/strmap.c +0 -100
  437. data/vendor/libgit2/src/util/strmap.h +0 -131
  438. /data/vendor/libgit2/cmake/{FindHTTPParser.cmake → FindHTTP_Parser.cmake} +0 -0
  439. /data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xdiff.h +0 -0
  440. /data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xemit.h +0 -0
  441. /data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xinclude.h +0 -0
  442. /data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xprepare.h +0 -0
  443. /data/vendor/libgit2/{src/libgit2 → deps}/xdiff/xtypes.h +0 -0
@@ -15,6 +15,7 @@
15
15
  #include "buf.h"
16
16
  #include "common.h"
17
17
  #include "commit.h"
18
+ #include "grafts.h"
18
19
  #include "tag.h"
19
20
  #include "blob.h"
20
21
  #include "futils.h"
@@ -33,7 +34,6 @@
33
34
  #include "submodule.h"
34
35
  #include "worktree.h"
35
36
  #include "path.h"
36
- #include "strmap.h"
37
37
 
38
38
  #ifdef GIT_WIN32
39
39
  # include "win32/w32_util.h"
@@ -61,12 +61,13 @@ static const struct {
61
61
  { GIT_REPOSITORY_ITEM_COMMONDIR, GIT_REPOSITORY_ITEM_GITDIR, "hooks", true },
62
62
  { GIT_REPOSITORY_ITEM_COMMONDIR, GIT_REPOSITORY_ITEM_GITDIR, "logs", true },
63
63
  { GIT_REPOSITORY_ITEM_GITDIR, GIT_REPOSITORY_ITEM__LAST, "modules", true },
64
- { 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 }
65
66
  };
66
67
 
67
68
  static int check_repositoryformatversion(int *version, git_config *config);
68
69
  static int check_extensions(git_config *config, int version);
69
- static int load_global_config(git_config **config);
70
+ static int load_global_config(git_config **config, bool use_env);
70
71
  static int load_objectformat(git_repository *repo, git_config *config);
71
72
 
72
73
  #define GIT_COMMONDIR_FILE "commondir"
@@ -151,6 +152,10 @@ int git_repository__cleanup(git_repository *repo)
151
152
  git_repository_submodule_cache_clear(repo);
152
153
  git_cache_clear(&repo->objects);
153
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;
154
159
 
155
160
  set_config(repo, NULL);
156
161
  set_index(repo, NULL);
@@ -191,11 +196,23 @@ void git_repository_free(git_repository *repo)
191
196
  }
192
197
 
193
198
  /* Check if we have a separate commondir (e.g. we have a worktree) */
194
- static int lookup_commondir(bool *separate, git_str *commondir, git_str *repository_path)
199
+ static int lookup_commondir(
200
+ bool *separate,
201
+ git_str *commondir,
202
+ git_str *repository_path,
203
+ uint32_t flags)
195
204
  {
196
- git_str common_link = GIT_STR_INIT;
205
+ git_str common_link = GIT_STR_INIT;
197
206
  int error;
198
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
+
199
216
  /*
200
217
  * If there's no commondir file, the repository path is the
201
218
  * common path, but it needs a trailing slash.
@@ -222,12 +239,11 @@ static int lookup_commondir(bool *separate, git_str *commondir, git_str *reposit
222
239
  git_str_swap(commondir, &common_link);
223
240
  }
224
241
 
225
- git_str_dispose(&common_link);
226
-
227
242
  /* Make sure the commondir path always has a trailing slash */
228
243
  error = git_fs_path_prettify_dir(commondir, commondir->ptr, NULL);
229
244
 
230
245
  done:
246
+ git_str_dispose(&common_link);
231
247
  return error;
232
248
  }
233
249
 
@@ -252,14 +268,19 @@ GIT_INLINE(int) validate_repo_path(git_str *path)
252
268
  *
253
269
  * Open a repository object from its path
254
270
  */
255
- static int is_valid_repository_path(bool *out, git_str *repository_path, git_str *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)
256
276
  {
257
277
  bool separate_commondir = false;
258
278
  int error;
259
279
 
260
280
  *out = false;
261
281
 
262
- 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)
263
284
  return error;
264
285
 
265
286
  /* Ensure HEAD file exists */
@@ -307,19 +328,34 @@ on_error:
307
328
  return NULL;
308
329
  }
309
330
 
310
- int git_repository_new(git_repository **out)
331
+ int git_repository__new(git_repository **out, git_oid_t oid_type)
311
332
  {
312
333
  git_repository *repo;
313
334
 
314
335
  *out = repo = repository_alloc();
315
336
  GIT_ERROR_CHECK_ALLOC(repo);
316
337
 
338
+ GIT_ASSERT_ARG(git_oid_type_is_valid(oid_type));
339
+
317
340
  repo->is_bare = 1;
318
341
  repo->is_worktree = 0;
342
+ repo->oid_type = oid_type;
319
343
 
320
344
  return 0;
321
345
  }
322
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
+
323
359
  static int load_config_data(git_repository *repo, const git_config *config)
324
360
  {
325
361
  int is_bare;
@@ -337,19 +373,42 @@ static int load_config_data(git_repository *repo, const git_config *config)
337
373
  return 0;
338
374
  }
339
375
 
340
- static int load_workdir(git_repository *repo, git_config *config, git_str *parent_path)
376
+ static int load_workdir(
377
+ git_repository *repo,
378
+ git_config *config,
379
+ git_str *parent_path)
341
380
  {
342
- int error;
343
- git_config_entry *ce;
381
+ git_config_entry *ce = NULL;
344
382
  git_str worktree = GIT_STR_INIT;
345
383
  git_str path = GIT_STR_INIT;
384
+ git_str workdir_env = GIT_STR_INIT;
385
+ const char *value = NULL;
386
+ int error;
346
387
 
347
388
  if (repo->is_bare)
348
389
  return 0;
349
390
 
350
- if ((error = git_config__lookup_entry(
351
- &ce, config, "core.worktree", false)) < 0)
352
- 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
+ }
353
412
 
354
413
  if (repo->is_worktree) {
355
414
  char *gitlink = git_worktree__read_link(repo->gitdir, GIT_GITDIR_FILE);
@@ -367,17 +426,21 @@ static int load_workdir(git_repository *repo, git_config *config, git_str *paren
367
426
  }
368
427
 
369
428
  repo->workdir = git_str_detach(&worktree);
370
- }
371
- else if (ce && ce->value) {
372
- if ((error = git_fs_path_prettify_dir(
373
- &worktree, ce->value, repo->gitdir)) < 0)
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;
433
+ goto cleanup;
434
+ }
435
+
436
+ if ((error = git_fs_path_prettify_dir(&worktree,
437
+ value, repo->gitdir)) < 0)
374
438
  goto cleanup;
375
439
 
376
440
  repo->workdir = git_str_detach(&worktree);
377
- }
378
- else if (parent_path && git_fs_path_isdir(parent_path->ptr))
441
+ } else if (parent_path && git_fs_path_isdir(parent_path->ptr)) {
379
442
  repo->workdir = git_str_detach(parent_path);
380
- else {
443
+ } else {
381
444
  if (git_fs_path_dirname_r(&worktree, repo->gitdir) < 0 ||
382
445
  git_fs_path_to_dir(&worktree) < 0) {
383
446
  error = -1;
@@ -388,8 +451,10 @@ static int load_workdir(git_repository *repo, git_config *config, git_str *paren
388
451
  }
389
452
 
390
453
  GIT_ERROR_CHECK_ALLOC(repo->workdir);
454
+
391
455
  cleanup:
392
456
  git_str_dispose(&path);
457
+ git_str_dispose(&workdir_env);
393
458
  git_config_entry_free(ce);
394
459
  return error;
395
460
  }
@@ -495,25 +560,39 @@ typedef struct {
495
560
  static int validate_ownership_cb(const git_config_entry *entry, void *payload)
496
561
  {
497
562
  validate_ownership_data *data = payload;
563
+ const char *test_path;
498
564
 
499
565
  if (strcmp(entry->value, "") == 0) {
500
566
  *data->is_safe = false;
501
567
  } else if (strcmp(entry->value, "*") == 0) {
502
568
  *data->is_safe = true;
503
569
  } else {
504
- const char *test_path = entry->value;
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;
505
584
 
506
- #ifdef GIT_WIN32
507
585
  /*
508
- * Git for Windows does some truly bizarre things with
509
- * paths that start with a forward slash; and expects you
510
- * to escape that with `%(prefix)`. This syntax generally
511
- * means to add the prefix that Git was installed to -- eg
512
- * `/usr/local` -- unless it's an absolute path, in which
513
- * case the leading `%(prefix)/` is just removed. And Git
514
- * for Windows expects you to use this syntax for absolute
515
- * Unix-style paths (in "Git Bash" or Windows Subsystem for
516
- * Linux).
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).
517
596
  *
518
597
  * Worse, the behavior used to be that a leading `/` was
519
598
  * not absolute. It would indicate that Git for Windows
@@ -528,20 +607,18 @@ static int validate_ownership_cb(const git_config_entry *entry, void *payload)
528
607
  */
529
608
  if (strncmp(test_path, "%(prefix)//", strlen("%(prefix)//")) == 0)
530
609
  test_path += strlen("%(prefix)/");
531
- else if (strncmp(test_path, "//", 2) == 0 &&
532
- strncmp(test_path, "//wsl.localhost/", strlen("//wsl.localhost/")) != 0)
533
- test_path++;
534
- #endif
535
610
 
536
- if (git_fs_path_prettify_dir(&data->tmp, test_path, NULL) == 0 &&
537
- strcmp(data->tmp.ptr, data->repo_path) == 0)
611
+ if (strcmp(test_path, data->repo_path) == 0)
538
612
  *data->is_safe = true;
539
613
  }
540
614
 
541
615
  return 0;
542
616
  }
543
617
 
544
- static int validate_ownership_config(bool *is_safe, const char *path)
618
+ static int validate_ownership_config(
619
+ bool *is_safe,
620
+ const char *path,
621
+ bool use_env)
545
622
  {
546
623
  validate_ownership_data ownership_data = {
547
624
  path, GIT_STR_INIT, is_safe
@@ -549,7 +626,7 @@ static int validate_ownership_config(bool *is_safe, const char *path)
549
626
  git_config *config;
550
627
  int error;
551
628
 
552
- if (load_global_config(&config) != 0)
629
+ if (load_global_config(&config, use_env) != 0)
553
630
  return 0;
554
631
 
555
632
  error = git_config_get_multivar_foreach(config,
@@ -623,13 +700,17 @@ static int validate_ownership(git_repository *repo)
623
700
  }
624
701
 
625
702
  if (is_safe ||
626
- (error = validate_ownership_config(&is_safe, validation_paths[0])) < 0)
703
+ (error = validate_ownership_config(
704
+ &is_safe, validation_paths[0], repo->use_env)) < 0)
627
705
  goto done;
628
706
 
629
707
  if (!is_safe) {
708
+ size_t path_len = git_fs_path_is_root(path) ?
709
+ strlen(path) : git_fs_path_dirlen(path);
710
+
630
711
  git_error_set(GIT_ERROR_CONFIG,
631
- "repository path '%s' is not owned by current user",
632
- path);
712
+ "repository path '%.*s' is not owned by current user",
713
+ (int)min(path_len, INT_MAX), path);
633
714
  error = GIT_EOWNER;
634
715
  }
635
716
 
@@ -637,14 +718,28 @@ done:
637
718
  return error;
638
719
  }
639
720
 
640
- static int find_repo(
641
- git_str *gitdir_path,
642
- git_str *workdir_path,
643
- git_str *gitlink_path,
644
- git_str *commondir_path,
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,
645
740
  const char *start_path,
646
- uint32_t flags,
647
- const char *ceiling_dirs)
741
+ const char *ceiling_dirs,
742
+ uint32_t flags)
648
743
  {
649
744
  git_str path = GIT_STR_INIT;
650
745
  git_str repo_link = GIT_STR_INIT;
@@ -656,19 +751,23 @@ static int find_repo(
656
751
  size_t ceiling_offset = 0;
657
752
  int error;
658
753
 
659
- git_str_clear(gitdir_path);
754
+ git_str_clear(&out->gitdir);
660
755
 
661
- error = git_fs_path_prettify(&path, start_path, NULL);
662
- if (error < 0)
756
+ if ((error = git_fs_path_prettify(&path, start_path, NULL)) < 0)
663
757
  return error;
664
758
 
665
- /* 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:
666
764
  * /a/b/c/.git, /a/b/c, /a/b/.git, /a/b, /a/.git, /a
667
- * With GIT_REPOSITORY_OPEN_BARE or GIT_REPOSITORY_OPEN_NO_DOTGIT, we
668
- * assume we started with /a/b/c.git and don't append .git the first
669
- * time through.
670
- * min_iterations indicates the number of iterations left before going
671
- * 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
+ */
672
771
  if (flags & (GIT_REPOSITORY_OPEN_BARE | GIT_REPOSITORY_OPEN_NO_DOTGIT)) {
673
772
  in_dot_git = true;
674
773
  min_iterations = 1;
@@ -695,48 +794,51 @@ static int find_repo(
695
794
  break;
696
795
 
697
796
  if (S_ISDIR(st.st_mode)) {
698
- 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)
699
798
  goto out;
700
799
 
701
800
  if (is_valid) {
702
801
  if ((error = git_fs_path_to_dir(&path)) < 0 ||
703
- (error = git_str_set(gitdir_path, path.ptr, path.size)) < 0)
802
+ (error = git_str_set(&out->gitdir, path.ptr, path.size)) < 0)
704
803
  goto out;
705
804
 
706
- if (gitlink_path)
707
- if ((error = git_str_attach(gitlink_path, git_worktree__read_link(path.ptr, GIT_GITDIR_FILE), 0)) < 0)
708
- goto out;
709
- if (commondir_path)
710
- git_str_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);
711
809
 
712
810
  break;
713
811
  }
714
812
  } else if (S_ISREG(st.st_mode) && git__suffixcmp(path.ptr, "/" DOT_GIT) == 0) {
715
813
  if ((error = read_gitfile(&repo_link, path.ptr)) < 0 ||
716
- (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)
717
815
  goto out;
718
816
 
719
817
  if (is_valid) {
720
- git_str_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;
721
822
 
722
- if (gitlink_path)
723
- if ((error = git_str_put(gitlink_path, path.ptr, path.size)) < 0)
724
- goto out;
725
- if (commondir_path)
726
- git_str_swap(&common_link, commondir_path);
823
+ git_str_swap(&common_link, &out->commondir);
727
824
  }
728
825
  break;
729
826
  }
730
827
  }
731
828
 
732
- /* Move up one directory. If we're in_dot_git, we'll search the
733
- * parent itself next. If we're !in_dot_git, we'll search .git
734
- * in the parent directory next (added at the top of the loop). */
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
+ */
735
835
  if ((error = git_fs_path_dirname_r(&path, path.ptr)) < 0)
736
836
  goto out;
737
837
 
738
- /* Once we've checked the directory (and .git if applicable),
739
- * 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
+ */
740
842
  if (min_iterations && (--min_iterations == 0))
741
843
  ceiling_offset = find_ceiling_dir_offset(path.ptr, ceiling_dirs);
742
844
 
@@ -746,29 +848,139 @@ static int find_repo(
746
848
  break;
747
849
  }
748
850
 
749
- if (workdir_path && !(flags & GIT_REPOSITORY_OPEN_BARE)) {
750
- if (!git_str_len(gitdir_path))
751
- git_str_clear(workdir_path);
752
- else if ((error = git_fs_path_dirname_r(workdir_path, path.ptr)) < 0 ||
753
- (error = git_fs_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)
754
856
  goto out;
755
857
  }
756
858
 
757
- /* If we didn't find the repository, and we don't have any other error
758
- * to report, report that. */
759
- if (!git_str_len(gitdir_path)) {
760
- 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);
761
863
  error = GIT_ENOTFOUND;
762
864
  goto out;
763
865
  }
764
866
 
765
867
  out:
868
+ if (error)
869
+ repo_paths_dispose(out);
870
+
766
871
  git_str_dispose(&path);
767
872
  git_str_dispose(&repo_link);
768
873
  git_str_dispose(&common_link);
769
874
  return error;
770
875
  }
771
876
 
877
+ static int load_grafts(git_repository *repo)
878
+ {
879
+ git_str path = GIT_STR_INIT;
880
+ int error;
881
+
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
+ }
888
+
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;
902
+ }
903
+
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;
908
+
909
+ git_str_clear(&path);
910
+
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;
914
+
915
+ error:
916
+ git_str_dispose(&path);
917
+ return error;
918
+ }
919
+
920
+ static int find_repo(
921
+ struct repo_paths *out,
922
+ const char *start_path,
923
+ const char *ceiling_dirs,
924
+ uint32_t flags)
925
+ {
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;
930
+ int error;
931
+
932
+ if (use_env && !start_path) {
933
+ error = git__getenv(&gitdir_buf, "GIT_DIR");
934
+
935
+ if (!error) {
936
+ start_path = gitdir_buf.ptr;
937
+ flags |= GIT_REPOSITORY_OPEN_NO_SEARCH;
938
+ flags |= GIT_REPOSITORY_OPEN_NO_DOTGIT;
939
+ } else if (error == GIT_ENOTFOUND) {
940
+ start_path = ".";
941
+ } else {
942
+ goto done;
943
+ }
944
+ }
945
+
946
+ if (use_env && !ceiling_dirs) {
947
+ error = git__getenv(&ceiling_dirs_buf,
948
+ "GIT_CEILING_DIRECTORIES");
949
+
950
+ if (!error)
951
+ ceiling_dirs = ceiling_dirs_buf.ptr;
952
+ else if (error != GIT_ENOTFOUND)
953
+ goto done;
954
+ }
955
+
956
+ if (use_env) {
957
+ error = git__getenv(&across_fs_buf,
958
+ "GIT_DISCOVERY_ACROSS_FILESYSTEM");
959
+
960
+ if (!error) {
961
+ int across_fs = 0;
962
+
963
+ if ((error = git_config_parse_bool(&across_fs,
964
+ git_str_cstr(&across_fs_buf))) < 0)
965
+ goto done;
966
+
967
+ if (across_fs)
968
+ flags |= GIT_REPOSITORY_OPEN_CROSS_FS;
969
+ } else if (error != GIT_ENOTFOUND) {
970
+ goto done;
971
+ }
972
+ }
973
+
974
+ error = find_repo_traverse(out, start_path, ceiling_dirs, flags);
975
+
976
+ done:
977
+ git_str_dispose(&gitdir_buf);
978
+ git_str_dispose(&ceiling_dirs_buf);
979
+ git_str_dispose(&across_fs_buf);
980
+
981
+ return error;
982
+ }
983
+
772
984
  static int obtain_config_and_set_oid_type(
773
985
  git_config **config_ptr,
774
986
  git_repository *repo)
@@ -787,7 +999,7 @@ static int obtain_config_and_set_oid_type(
787
999
  goto out;
788
1000
 
789
1001
  if (config &&
790
- (error = check_repositoryformatversion(&version, config)) < 0)
1002
+ (error = check_repositoryformatversion(&version, config)) < 0)
791
1003
  goto out;
792
1004
 
793
1005
  if ((error = check_extensions(config, version)) < 0)
@@ -797,7 +1009,7 @@ static int obtain_config_and_set_oid_type(
797
1009
  if ((error = load_objectformat(repo, config)) < 0)
798
1010
  goto out;
799
1011
  } else {
800
- repo->oid_type = GIT_OID_SHA1;
1012
+ repo->oid_type = GIT_OID_DEFAULT;
801
1013
  }
802
1014
 
803
1015
  out:
@@ -817,7 +1029,7 @@ int git_repository_open_bare(
817
1029
  git_config *config;
818
1030
 
819
1031
  if ((error = git_fs_path_prettify_dir(&path, bare_path, NULL)) < 0 ||
820
- (error = is_valid_repository_path(&is_valid, &path, &common_path)) < 0)
1032
+ (error = is_valid_repository_path(&is_valid, &path, &common_path, 0)) < 0)
821
1033
  return error;
822
1034
 
823
1035
  if (!is_valid) {
@@ -851,173 +1063,22 @@ cleanup:
851
1063
  return error;
852
1064
  }
853
1065
 
854
- static int _git_repository_open_ext_from_env(
855
- git_repository **out,
856
- const char *start_path)
1066
+ static int repo_load_namespace(git_repository *repo)
857
1067
  {
858
- git_repository *repo = NULL;
859
- git_index *index = NULL;
860
- git_odb *odb = NULL;
861
- git_str dir_buf = GIT_STR_INIT;
862
- git_str ceiling_dirs_buf = GIT_STR_INIT;
863
- git_str across_fs_buf = GIT_STR_INIT;
864
- git_str index_file_buf = GIT_STR_INIT;
865
1068
  git_str namespace_buf = GIT_STR_INIT;
866
- git_str object_dir_buf = GIT_STR_INIT;
867
- git_str alts_buf = GIT_STR_INIT;
868
- git_str work_tree_buf = GIT_STR_INIT;
869
- git_str common_dir_buf = GIT_STR_INIT;
870
- const char *ceiling_dirs = NULL;
871
- unsigned flags = 0;
872
1069
  int error;
873
1070
 
874
- if (!start_path) {
875
- error = git__getenv(&dir_buf, "GIT_DIR");
876
- if (error == GIT_ENOTFOUND) {
877
- git_error_clear();
878
- start_path = ".";
879
- } else if (error < 0)
880
- goto error;
881
- else {
882
- start_path = git_str_cstr(&dir_buf);
883
- flags |= GIT_REPOSITORY_OPEN_NO_SEARCH;
884
- flags |= GIT_REPOSITORY_OPEN_NO_DOTGIT;
885
- }
886
- }
887
-
888
- error = git__getenv(&ceiling_dirs_buf, "GIT_CEILING_DIRECTORIES");
889
- if (error == GIT_ENOTFOUND)
890
- git_error_clear();
891
- else if (error < 0)
892
- goto error;
893
- else
894
- ceiling_dirs = git_str_cstr(&ceiling_dirs_buf);
895
-
896
- error = git__getenv(&across_fs_buf, "GIT_DISCOVERY_ACROSS_FILESYSTEM");
897
- if (error == GIT_ENOTFOUND)
898
- git_error_clear();
899
- else if (error < 0)
900
- goto error;
901
- else {
902
- int across_fs = 0;
903
- error = git_config_parse_bool(&across_fs, git_str_cstr(&across_fs_buf));
904
- if (error < 0)
905
- goto error;
906
- if (across_fs)
907
- flags |= GIT_REPOSITORY_OPEN_CROSS_FS;
908
- }
909
-
910
- error = git__getenv(&index_file_buf, "GIT_INDEX_FILE");
911
- if (error == GIT_ENOTFOUND)
912
- git_error_clear();
913
- else if (error < 0)
914
- goto error;
915
- else {
916
- error = git_index_open(&index, git_str_cstr(&index_file_buf));
917
- if (error < 0)
918
- goto error;
919
- }
1071
+ if (!repo->use_env)
1072
+ return 0;
920
1073
 
921
1074
  error = git__getenv(&namespace_buf, "GIT_NAMESPACE");
922
- if (error == GIT_ENOTFOUND)
923
- git_error_clear();
924
- else if (error < 0)
925
- goto error;
926
-
927
- error = git__getenv(&object_dir_buf, "GIT_OBJECT_DIRECTORY");
928
- if (error == GIT_ENOTFOUND)
929
- git_error_clear();
930
- else if (error < 0)
931
- goto error;
932
- else {
933
- error = git_odb__open(&odb, git_str_cstr(&object_dir_buf), NULL);
934
- if (error < 0)
935
- goto error;
936
- }
937
1075
 
938
- error = git__getenv(&work_tree_buf, "GIT_WORK_TREE");
939
- if (error == GIT_ENOTFOUND)
940
- git_error_clear();
941
- else if (error < 0)
942
- goto error;
943
- else {
944
- git_error_set(GIT_ERROR_INVALID, "GIT_WORK_TREE unimplemented");
945
- error = GIT_ERROR;
946
- goto error;
947
- }
948
-
949
- error = git__getenv(&work_tree_buf, "GIT_COMMON_DIR");
950
- if (error == GIT_ENOTFOUND)
951
- git_error_clear();
952
- else if (error < 0)
953
- goto error;
954
- else {
955
- git_error_set(GIT_ERROR_INVALID, "GIT_COMMON_DIR unimplemented");
956
- error = GIT_ERROR;
957
- goto error;
958
- }
959
-
960
- error = git_repository_open_ext(&repo, start_path, flags, ceiling_dirs);
961
- if (error < 0)
962
- goto error;
963
-
964
- if (odb)
965
- git_repository_set_odb(repo, odb);
966
-
967
- error = git__getenv(&alts_buf, "GIT_ALTERNATE_OBJECT_DIRECTORIES");
968
- if (error == GIT_ENOTFOUND) {
969
- git_error_clear();
970
- error = 0;
971
- } else if (error < 0)
972
- goto error;
973
- else {
974
- const char *end;
975
- char *alt, *sep;
976
- if (!odb) {
977
- error = git_repository_odb(&odb, repo);
978
- if (error < 0)
979
- goto error;
980
- }
981
-
982
- end = git_str_cstr(&alts_buf) + git_str_len(&alts_buf);
983
- for (sep = alt = alts_buf.ptr; sep != end; alt = sep+1) {
984
- for (sep = alt; *sep && *sep != GIT_PATH_LIST_SEPARATOR; sep++)
985
- ;
986
- if (*sep)
987
- *sep = '\0';
988
- error = git_odb_add_disk_alternate(odb, alt);
989
- if (error < 0)
990
- goto error;
991
- }
992
- }
993
-
994
- if (git_str_len(&namespace_buf)) {
995
- error = git_repository_set_namespace(repo, git_str_cstr(&namespace_buf));
996
- if (error < 0)
997
- goto error;
998
- }
999
-
1000
- git_repository_set_index(repo, index);
1076
+ if (error == 0)
1077
+ repo->namespace = git_str_detach(&namespace_buf);
1078
+ else if (error != GIT_ENOTFOUND)
1079
+ return error;
1001
1080
 
1002
- if (out) {
1003
- *out = repo;
1004
- goto success;
1005
- }
1006
- error:
1007
- git_repository_free(repo);
1008
- success:
1009
- git_odb_free(odb);
1010
- git_index_free(index);
1011
- git_str_dispose(&common_dir_buf);
1012
- git_str_dispose(&work_tree_buf);
1013
- git_str_dispose(&alts_buf);
1014
- git_str_dispose(&object_dir_buf);
1015
- git_str_dispose(&namespace_buf);
1016
- git_str_dispose(&index_file_buf);
1017
- git_str_dispose(&across_fs_buf);
1018
- git_str_dispose(&ceiling_dirs_buf);
1019
- git_str_dispose(&dir_buf);
1020
- return error;
1081
+ return 0;
1021
1082
  }
1022
1083
 
1023
1084
  static int repo_is_worktree(unsigned *out, const git_repository *repo)
@@ -1049,21 +1110,16 @@ int git_repository_open_ext(
1049
1110
  unsigned int flags,
1050
1111
  const char *ceiling_dirs)
1051
1112
  {
1052
- int error;
1053
- unsigned is_worktree;
1054
- git_str gitdir = GIT_STR_INIT, workdir = GIT_STR_INIT,
1055
- gitlink = GIT_STR_INIT, commondir = GIT_STR_INIT;
1113
+ struct repo_paths paths = { GIT_STR_INIT };
1056
1114
  git_repository *repo = NULL;
1057
1115
  git_config *config = NULL;
1058
-
1059
- if (flags & GIT_REPOSITORY_OPEN_FROM_ENV)
1060
- return _git_repository_open_ext_from_env(repo_ptr, start_path);
1116
+ unsigned is_worktree;
1117
+ int error;
1061
1118
 
1062
1119
  if (repo_ptr)
1063
1120
  *repo_ptr = NULL;
1064
1121
 
1065
- error = find_repo(
1066
- &gitdir, &workdir, &gitlink, &commondir, start_path, flags, ceiling_dirs);
1122
+ error = find_repo(&paths, start_path, ceiling_dirs, flags);
1067
1123
 
1068
1124
  if (error < 0 || !repo_ptr)
1069
1125
  goto cleanup;
@@ -1071,35 +1127,44 @@ int git_repository_open_ext(
1071
1127
  repo = repository_alloc();
1072
1128
  GIT_ERROR_CHECK_ALLOC(repo);
1073
1129
 
1074
- repo->gitdir = git_str_detach(&gitdir);
1130
+ repo->use_env = !!(flags & GIT_REPOSITORY_OPEN_FROM_ENV);
1131
+
1132
+ repo->gitdir = git_str_detach(&paths.gitdir);
1075
1133
  GIT_ERROR_CHECK_ALLOC(repo->gitdir);
1076
1134
 
1077
- if (gitlink.size) {
1078
- repo->gitlink = git_str_detach(&gitlink);
1135
+ if (paths.gitlink.size) {
1136
+ repo->gitlink = git_str_detach(&paths.gitlink);
1079
1137
  GIT_ERROR_CHECK_ALLOC(repo->gitlink);
1080
1138
  }
1081
- if (commondir.size) {
1082
- repo->commondir = git_str_detach(&commondir);
1139
+ if (paths.commondir.size) {
1140
+ repo->commondir = git_str_detach(&paths.commondir);
1083
1141
  GIT_ERROR_CHECK_ALLOC(repo->commondir);
1084
1142
  }
1085
1143
 
1086
1144
  if ((error = repo_is_worktree(&is_worktree, repo)) < 0)
1087
1145
  goto cleanup;
1146
+
1088
1147
  repo->is_worktree = is_worktree;
1089
1148
 
1090
1149
  error = obtain_config_and_set_oid_type(&config, repo);
1091
1150
  if (error < 0)
1092
1151
  goto cleanup;
1093
1152
 
1153
+ if ((error = load_grafts(repo)) < 0)
1154
+ goto cleanup;
1155
+
1094
1156
  if ((flags & GIT_REPOSITORY_OPEN_BARE) != 0) {
1095
1157
  repo->is_bare = 1;
1096
1158
  } else {
1097
1159
  if (config &&
1098
1160
  ((error = load_config_data(repo, config)) < 0 ||
1099
- (error = load_workdir(repo, config, &workdir)) < 0))
1161
+ (error = load_workdir(repo, config, &paths.workdir)) < 0))
1100
1162
  goto cleanup;
1101
1163
  }
1102
1164
 
1165
+ if ((error = repo_load_namespace(repo)) < 0)
1166
+ goto cleanup;
1167
+
1103
1168
  /*
1104
1169
  * Ensure that the git directory and worktree are
1105
1170
  * owned by the current user.
@@ -1109,10 +1174,7 @@ int git_repository_open_ext(
1109
1174
  goto cleanup;
1110
1175
 
1111
1176
  cleanup:
1112
- git_str_dispose(&gitdir);
1113
- git_str_dispose(&workdir);
1114
- git_str_dispose(&gitlink);
1115
- git_str_dispose(&commondir);
1177
+ repo_paths_dispose(&paths);
1116
1178
  git_config_free(config);
1117
1179
 
1118
1180
  if (error < 0)
@@ -1161,15 +1223,18 @@ out:
1161
1223
  return err;
1162
1224
  }
1163
1225
 
1164
- int git_repository_wrap_odb(git_repository **repo_out, git_odb *odb)
1226
+ int git_repository_wrap_odb(git_repository **out, git_odb *odb)
1165
1227
  {
1166
1228
  git_repository *repo;
1167
1229
 
1168
1230
  repo = repository_alloc();
1169
1231
  GIT_ERROR_CHECK_ALLOC(repo);
1170
1232
 
1233
+ GIT_ASSERT(git_oid_type_is_valid(odb->options.oid_type));
1234
+ repo->oid_type = odb->options.oid_type;
1235
+
1171
1236
  git_repository_set_odb(repo, odb);
1172
- *repo_out = repo;
1237
+ *out = repo;
1173
1238
 
1174
1239
  return 0;
1175
1240
  }
@@ -1180,11 +1245,35 @@ int git_repository_discover(
1180
1245
  int across_fs,
1181
1246
  const char *ceiling_dirs)
1182
1247
  {
1248
+ struct repo_paths paths = { GIT_STR_INIT };
1183
1249
  uint32_t flags = across_fs ? GIT_REPOSITORY_OPEN_CROSS_FS : 0;
1250
+ int error;
1184
1251
 
1185
1252
  GIT_ASSERT_ARG(start_path);
1186
1253
 
1187
- GIT_BUF_WRAP_PRIVATE(out, find_repo, NULL, NULL, NULL, start_path, flags, ceiling_dirs);
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
1274
+ return error;
1275
+
1276
+ return 0;
1188
1277
  }
1189
1278
 
1190
1279
  static int load_config(
@@ -1195,9 +1284,11 @@ static int load_config(
1195
1284
  const char *system_config_path,
1196
1285
  const char *programdata_path)
1197
1286
  {
1198
- int error;
1199
1287
  git_str config_path = GIT_STR_INIT;
1200
1288
  git_config *cfg = NULL;
1289
+ git_config_level_t write_order;
1290
+ bool has_worktree;
1291
+ int error;
1201
1292
 
1202
1293
  GIT_ASSERT_ARG(out);
1203
1294
 
@@ -1211,6 +1302,14 @@ static int load_config(
1211
1302
  if (error && error != GIT_ENOTFOUND)
1212
1303
  goto on_error;
1213
1304
 
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
+
1214
1313
  git_str_dispose(&config_path);
1215
1314
  }
1216
1315
 
@@ -1240,6 +1339,11 @@ static int load_config(
1240
1339
 
1241
1340
  git_error_clear(); /* clear any lingering ENOTFOUND errors */
1242
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
+
1243
1347
  *out = cfg;
1244
1348
  return 0;
1245
1349
 
@@ -1255,32 +1359,81 @@ static const char *path_unless_empty(git_str *buf)
1255
1359
  return git_str_len(buf) > 0 ? git_str_cstr(buf) : NULL;
1256
1360
  }
1257
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)
1391
+ {
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;
1401
+ }
1402
+
1258
1403
  int git_repository_config__weakptr(git_config **out, git_repository *repo)
1259
1404
  {
1260
1405
  int error = 0;
1261
1406
 
1262
1407
  if (repo->_config == NULL) {
1408
+ git_str system_buf = GIT_STR_INIT;
1263
1409
  git_str global_buf = GIT_STR_INIT;
1264
1410
  git_str xdg_buf = GIT_STR_INIT;
1265
- git_str system_buf = GIT_STR_INIT;
1266
1411
  git_str programdata_buf = GIT_STR_INIT;
1412
+ bool use_env = repo->use_env;
1267
1413
  git_config *config;
1268
1414
 
1269
- git_config__find_global(&global_buf);
1270
- git_config__find_xdg(&xdg_buf);
1271
- git_config__find_system(&system_buf);
1272
- git_config__find_programdata(&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
+ }
1273
1420
 
1274
- /* If there is no global file, open a backend for it anyway */
1275
- if (git_str_len(&global_buf) == 0)
1276
- git_config__global_location(&global_buf);
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
+ }
1277
1436
 
1278
- error = load_config(
1279
- &config, repo,
1280
- path_unless_empty(&global_buf),
1281
- path_unless_empty(&xdg_buf),
1282
- path_unless_empty(&system_buf),
1283
- path_unless_empty(&programdata_buf));
1284
1437
  if (!error) {
1285
1438
  GIT_REFCOUNT_OWN(config, repo);
1286
1439
 
@@ -1329,6 +1482,56 @@ int git_repository_set_config(git_repository *repo, git_config *config)
1329
1482
  return 0;
1330
1483
  }
1331
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)
1502
+ {
1503
+ git_str alternates = GIT_STR_INIT;
1504
+ char *sep, *alt;
1505
+ int error;
1506
+
1507
+ if (!repo->use_env)
1508
+ return 0;
1509
+
1510
+ error = git__getenv(&alternates, "GIT_ALTERNATE_OBJECT_DIRECTORIES");
1511
+
1512
+ if (error != 0)
1513
+ return (error == GIT_ENOTFOUND) ? 0 : error;
1514
+
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);
1532
+ return 0;
1533
+ }
1534
+
1332
1535
  int git_repository_odb__weakptr(git_odb **out, git_repository *repo)
1333
1536
  {
1334
1537
  int error = 0;
@@ -1344,9 +1547,9 @@ int git_repository_odb__weakptr(git_odb **out, git_repository *repo)
1344
1547
 
1345
1548
  odb_opts.oid_type = repo->oid_type;
1346
1549
 
1347
- if ((error = git_repository__item_path(&odb_path, repo,
1348
- GIT_REPOSITORY_ITEM_OBJECTS)) < 0 ||
1349
- (error = git_odb__new(&odb, &odb_opts)) < 0)
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)
1350
1553
  return error;
1351
1554
 
1352
1555
  GIT_REFCOUNT_OWN(odb, repo);
@@ -1430,6 +1633,20 @@ int git_repository_set_refdb(git_repository *repo, git_refdb *refdb)
1430
1633
  return 0;
1431
1634
  }
1432
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
+
1433
1650
  int git_repository_index__weakptr(git_index **out, git_repository *repo)
1434
1651
  {
1435
1652
  int error = 0;
@@ -1441,10 +1658,11 @@ int git_repository_index__weakptr(git_index **out, git_repository *repo)
1441
1658
  git_str index_path = GIT_STR_INIT;
1442
1659
  git_index *index;
1443
1660
 
1444
- if ((error = git_str_joinpath(&index_path, repo->gitdir, GIT_INDEX_FILE)) < 0)
1661
+ if ((error = repository_index_path(&index_path, repo)) < 0)
1445
1662
  return error;
1446
1663
 
1447
- error = git_index_open(&index, index_path.ptr);
1664
+ error = git_index__open(&index, index_path.ptr, repo->oid_type);
1665
+
1448
1666
  if (!error) {
1449
1667
  GIT_REFCOUNT_OWN(index, repo);
1450
1668
 
@@ -1480,6 +1698,22 @@ int git_repository_set_index(git_repository *repo, git_index *index)
1480
1698
  return 0;
1481
1699
  }
1482
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
+
1483
1717
  int git_repository_set_namespace(git_repository *repo, const char *namespace)
1484
1718
  {
1485
1719
  git__free(repo->namespace);
@@ -1629,10 +1863,12 @@ static int check_repositoryformatversion(int *version, git_config *config)
1629
1863
 
1630
1864
  static const char *builtin_extensions[] = {
1631
1865
  "noop",
1632
- "objectformat"
1866
+ "objectformat",
1867
+ "worktreeconfig",
1868
+ "preciousobjects"
1633
1869
  };
1634
1870
 
1635
- static git_vector user_extensions = GIT_VECTOR_INIT;
1871
+ static git_vector user_extensions = { 0, git__strcmp_cb };
1636
1872
 
1637
1873
  static int check_valid_extension(const git_config_entry *entry, void *payload)
1638
1874
  {
@@ -1700,7 +1936,7 @@ static int load_objectformat(git_repository *repo, git_config *config)
1700
1936
 
1701
1937
  if ((error = git_config_get_entry(&entry, config, "extensions.objectformat")) < 0) {
1702
1938
  if (error == GIT_ENOTFOUND) {
1703
- repo->oid_type = GIT_OID_SHA1;
1939
+ repo->oid_type = GIT_OID_DEFAULT;
1704
1940
  git_error_clear();
1705
1941
  error = 0;
1706
1942
  }
@@ -1773,7 +2009,7 @@ int git_repository__extensions(char ***out, size_t *out_len)
1773
2009
  char *extension;
1774
2010
  size_t i, j;
1775
2011
 
1776
- if (git_vector_init(&extensions, 8, NULL) < 0)
2012
+ if (git_vector_init(&extensions, 8, git__strcmp_cb) < 0)
1777
2013
  return -1;
1778
2014
 
1779
2015
  for (i = 0; i < ARRAY_SIZE(builtin_extensions); i++) {
@@ -1805,21 +2041,49 @@ int git_repository__extensions(char ***out, size_t *out_len)
1805
2041
  return -1;
1806
2042
  }
1807
2043
 
2044
+ git_vector_sort(&extensions);
2045
+
1808
2046
  *out = (char **)git_vector_detach(out_len, NULL, &extensions);
1809
2047
  return 0;
1810
2048
  }
1811
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
+
1812
2057
  int git_repository__set_extensions(const char **extensions, size_t len)
1813
2058
  {
1814
2059
  char *extension;
1815
- size_t i;
2060
+ size_t i, j;
2061
+ int error;
1816
2062
 
1817
2063
  git_repository__free_extensions();
1818
2064
 
1819
2065
  for (i = 0; i < len; i++) {
1820
- if ((extension = git__strdup(extensions[i])) == NULL ||
1821
- 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)
1822
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
+ }
1823
2087
  }
1824
2088
 
1825
2089
  return 0;
@@ -1827,7 +2091,7 @@ int git_repository__set_extensions(const char **extensions, size_t len)
1827
2091
 
1828
2092
  void git_repository__free_extensions(void)
1829
2093
  {
1830
- git_vector_free_deep(&user_extensions);
2094
+ git_vector_dispose_deep(&user_extensions);
1831
2095
  }
1832
2096
 
1833
2097
  int git_repository_create_head(const char *git_dir, const char *ref_name)
@@ -1888,7 +2152,7 @@ static bool is_filesystem_case_insensitive(const char *gitdir_path)
1888
2152
  * Return a configuration object with only the global and system
1889
2153
  * configurations; no repository-level configuration.
1890
2154
  */
1891
- static int load_global_config(git_config **config)
2155
+ static int load_global_config(git_config **config, bool use_env)
1892
2156
  {
1893
2157
  git_str global_buf = GIT_STR_INIT;
1894
2158
  git_str xdg_buf = GIT_STR_INIT;
@@ -1896,16 +2160,17 @@ static int load_global_config(git_config **config)
1896
2160
  git_str programdata_buf = GIT_STR_INIT;
1897
2161
  int error;
1898
2162
 
1899
- git_config__find_global(&global_buf);
1900
- git_config__find_xdg(&xdg_buf);
1901
- git_config__find_system(&system_buf);
1902
- git_config__find_programdata(&programdata_buf);
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);
1903
2167
 
1904
- error = load_config(config, NULL,
1905
- path_unless_empty(&global_buf),
1906
- path_unless_empty(&xdg_buf),
1907
- path_unless_empty(&system_buf),
1908
- path_unless_empty(&programdata_buf));
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
+ }
1909
2174
 
1910
2175
  git_str_dispose(&global_buf);
1911
2176
  git_str_dispose(&xdg_buf);
@@ -1915,7 +2180,7 @@ static int load_global_config(git_config **config)
1915
2180
  return error;
1916
2181
  }
1917
2182
 
1918
- static bool are_symlinks_supported(const char *wd_path)
2183
+ static bool are_symlinks_supported(const char *wd_path, bool use_env)
1919
2184
  {
1920
2185
  git_config *config = NULL;
1921
2186
  int symlinks = 0;
@@ -1928,10 +2193,12 @@ static bool are_symlinks_supported(const char *wd_path)
1928
2193
  * _not_ set, then we do not test or enable symlink support.
1929
2194
  */
1930
2195
  #ifdef GIT_WIN32
1931
- if (load_global_config(&config) < 0 ||
2196
+ if (load_global_config(&config, use_env) < 0 ||
1932
2197
  git_config_get_bool(&symlinks, config, "core.symlinks") < 0 ||
1933
2198
  !symlinks)
1934
2199
  goto done;
2200
+ #else
2201
+ GIT_UNUSED(use_env);
1935
2202
  #endif
1936
2203
 
1937
2204
  if (!(symlinks = git_fs_path_supports_symlinks(wd_path)))
@@ -2004,7 +2271,8 @@ static int repo_init_fs_configs(
2004
2271
  const char *cfg_path,
2005
2272
  const char *repo_dir,
2006
2273
  const char *work_dir,
2007
- bool update_ignorecase)
2274
+ bool update_ignorecase,
2275
+ bool use_env)
2008
2276
  {
2009
2277
  int error = 0;
2010
2278
 
@@ -2015,7 +2283,7 @@ static int repo_init_fs_configs(
2015
2283
  cfg, "core.filemode", is_chmod_supported(cfg_path))) < 0)
2016
2284
  return error;
2017
2285
 
2018
- if (!are_symlinks_supported(work_dir)) {
2286
+ if (!are_symlinks_supported(work_dir, use_env)) {
2019
2287
  if ((error = git_config_set_bool(cfg, "core.symlinks", false)) < 0)
2020
2288
  return error;
2021
2289
  } else if (git_config_delete_entry(cfg, "core.symlinks") < 0)
@@ -2052,6 +2320,7 @@ static int repo_init_config(
2052
2320
  git_config *config = NULL;
2053
2321
  bool is_bare = ((flags & GIT_REPOSITORY_INIT_BARE) != 0);
2054
2322
  bool is_reinit = ((flags & GIT_REPOSITORY_INIT__IS_REINIT) != 0);
2323
+ bool use_env = ((flags & GIT_REPOSITORY_OPEN_FROM_ENV) != 0);
2055
2324
  int version = GIT_REPO_VERSION_DEFAULT;
2056
2325
 
2057
2326
  if ((error = repo_local_config(&config, &cfg_path, NULL, repo_dir)) < 0)
@@ -2072,7 +2341,8 @@ static int repo_init_config(
2072
2341
  SET_REPO_CONFIG(int32, "core.repositoryformatversion", version);
2073
2342
 
2074
2343
  if ((error = repo_init_fs_configs(
2075
- 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)
2076
2346
  goto cleanup;
2077
2347
 
2078
2348
  if (!is_bare) {
@@ -2102,7 +2372,7 @@ static int repo_init_config(
2102
2372
  SET_REPO_CONFIG(bool, "receive.denyNonFastforwards", true);
2103
2373
  }
2104
2374
 
2105
- if (oid_type != GIT_OID_SHA1) {
2375
+ if (oid_type != GIT_OID_DEFAULT) {
2106
2376
  SET_REPO_CONFIG(int32, "core.repositoryformatversion", 1);
2107
2377
  SET_REPO_CONFIG(string, "extensions.objectformat", git_oid_type_name(oid_type));
2108
2378
  }
@@ -2136,8 +2406,8 @@ int git_repository_reinit_filesystem(git_repository *repo, int recurse)
2136
2406
  const char *repo_dir = git_repository_path(repo);
2137
2407
 
2138
2408
  if (!(error = repo_local_config(&config, &path, repo, repo_dir)))
2139
- error = repo_init_fs_configs(
2140
- 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);
2141
2411
 
2142
2412
  git_config_free(config);
2143
2413
  git_str_dispose(&path);
@@ -2236,7 +2506,7 @@ static int repo_write_gitlink(
2236
2506
  error = git_fs_path_make_relative(&path_to_repo, in_dir);
2237
2507
 
2238
2508
  if (!error)
2239
- error = git_str_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);
2240
2510
 
2241
2511
  if (!error)
2242
2512
  error = repo_write_template(in_dir, true, DOT_GIT, 0666, true, buf.ptr);
@@ -2268,7 +2538,8 @@ static int repo_init_structure(
2268
2538
  int error = 0;
2269
2539
  repo_template_item *tpl;
2270
2540
  bool external_tpl =
2271
- ((opts->flags & GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE) != 0);
2541
+ opts->template_path != NULL ||
2542
+ (opts->flags & GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE) != 0;
2272
2543
  mode_t dmode = pick_dir_mode(opts);
2273
2544
  bool chmod = opts->mode != GIT_REPOSITORY_INIT_SHARED_UMASK;
2274
2545
 
@@ -2427,6 +2698,8 @@ static int repo_init_directories(
2427
2698
  if (git_str_joinpath(repo_path, given_repo, add_dotgit ? GIT_DIR : "") < 0)
2428
2699
  return -1;
2429
2700
 
2701
+ git_fs_path_mkposix(repo_path->ptr);
2702
+
2430
2703
  has_dotgit = (git__suffixcmp(repo_path->ptr, "/" GIT_DIR) == 0);
2431
2704
  if (has_dotgit)
2432
2705
  opts->flags |= GIT_REPOSITORY_INIT__HAS_DOTGIT;
@@ -2606,7 +2879,7 @@ int git_repository_init_ext(
2606
2879
 
2607
2880
  wd = (opts->flags & GIT_REPOSITORY_INIT_BARE) ? NULL : git_str_cstr(&wd_path);
2608
2881
 
2609
- 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)
2610
2883
  goto out;
2611
2884
 
2612
2885
  if (is_valid) {
@@ -2994,14 +3267,18 @@ int git_repository_set_workdir(
2994
3267
  if (git_fs_path_prettify_dir(&path, workdir, NULL) < 0)
2995
3268
  return -1;
2996
3269
 
2997
- if (repo->workdir && strcmp(repo->workdir, path.ptr) == 0)
3270
+ if (repo->workdir && strcmp(repo->workdir, path.ptr) == 0) {
3271
+ git_str_dispose(&path);
2998
3272
  return 0;
3273
+ }
2999
3274
 
3000
3275
  if (update_gitlink) {
3001
3276
  git_config *config;
3002
3277
 
3003
- if (git_repository_config__weakptr(&config, repo) < 0)
3278
+ if (git_repository_config__weakptr(&config, repo) < 0) {
3279
+ git_str_dispose(&path);
3004
3280
  return -1;
3281
+ }
3005
3282
 
3006
3283
  error = repo_write_gitlink(path.ptr, git_repository_path(repo), false);
3007
3284
 
@@ -3023,6 +3300,7 @@ int git_repository_set_workdir(
3023
3300
 
3024
3301
  git__free(old_workdir);
3025
3302
  }
3303
+ git_str_dispose(&path);
3026
3304
 
3027
3305
  return error;
3028
3306
  }
@@ -3065,6 +3343,25 @@ int git_repository_set_bare(git_repository *repo)
3065
3343
  return 0;
3066
3344
  }
3067
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
+
3068
3365
  int git_repository_head_tree(git_tree **tree, git_repository *repo)
3069
3366
  {
3070
3367
  git_reference *head;
@@ -3221,12 +3518,18 @@ cleanup:
3221
3518
 
3222
3519
  static int checkout_message(git_str *out, git_reference *old, const char *new)
3223
3520
  {
3521
+ const char *idstr;
3522
+
3224
3523
  git_str_puts(out, "checkout: moving from ");
3225
3524
 
3226
- if (git_reference_type(old) == GIT_REFERENCE_SYMBOLIC)
3525
+ if (git_reference_type(old) == GIT_REFERENCE_SYMBOLIC) {
3227
3526
  git_str_puts(out, git_reference__shorthand(git_reference_symbolic_target(old)));
3228
- else
3229
- git_str_puts(out, git_oid_tostr_s(git_reference_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
+ }
3230
3533
 
3231
3534
  git_str_puts(out, " to ");
3232
3535
 
@@ -3262,8 +3565,11 @@ static int detach(git_repository *repo, const git_oid *id, const char *new)
3262
3565
  if ((error = git_object_peel(&peeled, object, GIT_OBJECT_COMMIT)) < 0)
3263
3566
  goto cleanup;
3264
3567
 
3265
- if (new == NULL)
3266
- 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
+ }
3267
3573
 
3268
3574
  if ((error = checkout_message(&log_message, current, new)) < 0)
3269
3575
  goto cleanup;
@@ -3351,6 +3657,7 @@ int git_repository_detach_head(git_repository *repo)
3351
3657
  git_reference *old_head = NULL, *new_head = NULL, *current = NULL;
3352
3658
  git_object *object = NULL;
3353
3659
  git_str log_message = GIT_STR_INIT;
3660
+ const char *idstr;
3354
3661
  int error;
3355
3662
 
3356
3663
  GIT_ASSERT_ARG(repo);
@@ -3364,7 +3671,12 @@ int git_repository_detach_head(git_repository *repo)
3364
3671
  if ((error = git_object_lookup(&object, repo, git_reference_target(old_head), GIT_OBJECT_COMMIT)) < 0)
3365
3672
  goto cleanup;
3366
3673
 
3367
- 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)
3368
3680
  goto cleanup;
3369
3681
 
3370
3682
  error = git_reference_create(&new_head, repo, GIT_HEAD_FILE, git_reference_target(old_head),
@@ -3470,6 +3782,66 @@ int git_repository_state_cleanup(git_repository *repo)
3470
3782
  return git_repository__cleanup_files(repo, state_files, ARRAY_SIZE(state_files));
3471
3783
  }
3472
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
+
3473
3845
  int git_repository_is_shallow(git_repository *repo)
3474
3846
  {
3475
3847
  git_str path = GIT_STR_INIT;
@@ -3489,6 +3861,7 @@ int git_repository_is_shallow(git_repository *repo)
3489
3861
 
3490
3862
  if (error < 0)
3491
3863
  return error;
3864
+
3492
3865
  return st.st_size == 0 ? 0 : 1;
3493
3866
  }
3494
3867
 
@@ -3560,3 +3933,89 @@ git_oid_t git_repository_oid_type(git_repository *repo)
3560
3933
  {
3561
3934
  return repo ? repo->oid_type : 0;
3562
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
+ }