rugged 0.27.7 → 0.27.10

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 (409) hide show
  1. checksums.yaml +4 -4
  2. data/lib/rugged/version.rb +1 -1
  3. data/vendor/libgit2/AUTHORS +1 -0
  4. data/vendor/libgit2/CMakeLists.txt +99 -51
  5. data/vendor/libgit2/COPYING +28 -0
  6. data/vendor/libgit2/cmake/Modules/AddCFlagIfSupported.cmake +15 -1
  7. data/vendor/libgit2/cmake/Modules/CheckPrototypeDefinition.c.in +29 -0
  8. data/vendor/libgit2/cmake/Modules/CheckPrototypeDefinition.cmake +96 -0
  9. data/vendor/libgit2/cmake/Modules/EnableWarnings.cmake +9 -8
  10. data/vendor/libgit2/cmake/Modules/FindCoreFoundation.cmake +2 -2
  11. data/vendor/libgit2/cmake/Modules/FindGSSAPI.cmake +1 -1
  12. data/vendor/libgit2/cmake/Modules/FindGSSFramework.cmake +28 -0
  13. data/vendor/libgit2/cmake/Modules/FindIconv.cmake +11 -6
  14. data/vendor/libgit2/cmake/Modules/FindPCRE.cmake +38 -0
  15. data/vendor/libgit2/cmake/Modules/FindPCRE2.cmake +37 -0
  16. data/vendor/libgit2/cmake/Modules/FindSecurity.cmake +2 -2
  17. data/vendor/libgit2/cmake/Modules/FindStatNsec.cmake +6 -0
  18. data/vendor/libgit2/cmake/Modules/PkgBuildConfig.cmake +110 -0
  19. data/vendor/libgit2/cmake/Modules/SelectGSSAPI.cmake +53 -0
  20. data/vendor/libgit2/cmake/Modules/SelectHTTPSBackend.cmake +124 -0
  21. data/vendor/libgit2/cmake/Modules/SelectHashes.cmake +66 -0
  22. data/vendor/libgit2/deps/http-parser/http_parser.c +11 -6
  23. data/vendor/libgit2/deps/ntlmclient/CMakeLists.txt +21 -0
  24. data/vendor/libgit2/deps/ntlmclient/compat.h +33 -0
  25. data/vendor/libgit2/deps/ntlmclient/crypt.h +64 -0
  26. data/vendor/libgit2/deps/ntlmclient/crypt_commoncrypto.c +120 -0
  27. data/vendor/libgit2/deps/ntlmclient/crypt_commoncrypto.h +18 -0
  28. data/vendor/libgit2/deps/ntlmclient/crypt_mbedtls.c +145 -0
  29. data/vendor/libgit2/deps/ntlmclient/crypt_mbedtls.h +18 -0
  30. data/vendor/libgit2/deps/ntlmclient/crypt_openssl.c +130 -0
  31. data/vendor/libgit2/deps/ntlmclient/crypt_openssl.h +21 -0
  32. data/vendor/libgit2/deps/ntlmclient/ntlm.c +1420 -0
  33. data/vendor/libgit2/deps/ntlmclient/ntlm.h +174 -0
  34. data/vendor/libgit2/deps/ntlmclient/ntlmclient.h +320 -0
  35. data/vendor/libgit2/deps/ntlmclient/unicode.h +36 -0
  36. data/vendor/libgit2/deps/ntlmclient/unicode_builtin.c +445 -0
  37. data/vendor/libgit2/deps/ntlmclient/unicode_iconv.c +201 -0
  38. data/vendor/libgit2/deps/ntlmclient/utf8.h +1257 -0
  39. data/vendor/libgit2/deps/ntlmclient/util.c +21 -0
  40. data/vendor/libgit2/deps/ntlmclient/util.h +14 -0
  41. data/vendor/libgit2/deps/pcre/CMakeLists.txt +140 -0
  42. data/vendor/libgit2/deps/pcre/COPYING +5 -0
  43. data/vendor/libgit2/deps/pcre/cmake/COPYING-CMAKE-SCRIPTS +22 -0
  44. data/vendor/libgit2/deps/pcre/cmake/FindEditline.cmake +17 -0
  45. data/vendor/libgit2/deps/pcre/cmake/FindPackageHandleStandardArgs.cmake +58 -0
  46. data/vendor/libgit2/deps/pcre/cmake/FindReadline.cmake +29 -0
  47. data/vendor/libgit2/deps/pcre/config.h.in +57 -0
  48. data/vendor/libgit2/deps/pcre/pcre.h +641 -0
  49. data/vendor/libgit2/deps/pcre/pcre_byte_order.c +319 -0
  50. data/vendor/libgit2/deps/pcre/pcre_chartables.c +198 -0
  51. data/vendor/libgit2/deps/pcre/pcre_compile.c +9800 -0
  52. data/vendor/libgit2/deps/pcre/pcre_config.c +190 -0
  53. data/vendor/libgit2/deps/pcre/pcre_dfa_exec.c +3676 -0
  54. data/vendor/libgit2/deps/pcre/pcre_exec.c +7173 -0
  55. data/vendor/libgit2/deps/pcre/pcre_fullinfo.c +245 -0
  56. data/vendor/libgit2/deps/pcre/pcre_get.c +669 -0
  57. data/vendor/libgit2/deps/pcre/pcre_globals.c +86 -0
  58. data/vendor/libgit2/deps/pcre/pcre_internal.h +2787 -0
  59. data/vendor/libgit2/deps/pcre/pcre_jit_compile.c +11913 -0
  60. data/vendor/libgit2/deps/pcre/pcre_maketables.c +156 -0
  61. data/vendor/libgit2/deps/pcre/pcre_newline.c +210 -0
  62. data/vendor/libgit2/deps/pcre/pcre_ord2utf8.c +94 -0
  63. data/vendor/libgit2/deps/pcre/pcre_printint.c +834 -0
  64. data/vendor/libgit2/deps/pcre/pcre_refcount.c +92 -0
  65. data/vendor/libgit2/deps/pcre/pcre_string_utils.c +211 -0
  66. data/vendor/libgit2/deps/pcre/pcre_study.c +1686 -0
  67. data/vendor/libgit2/deps/pcre/pcre_tables.c +727 -0
  68. data/vendor/libgit2/deps/pcre/pcre_ucd.c +3644 -0
  69. data/vendor/libgit2/deps/pcre/pcre_valid_utf8.c +301 -0
  70. data/vendor/libgit2/deps/pcre/pcre_version.c +98 -0
  71. data/vendor/libgit2/deps/pcre/pcre_xclass.c +268 -0
  72. data/vendor/libgit2/deps/pcre/pcreposix.c +421 -0
  73. data/vendor/libgit2/deps/pcre/pcreposix.h +117 -0
  74. data/vendor/libgit2/deps/pcre/ucp.h +224 -0
  75. data/vendor/libgit2/deps/winhttp/COPYING.GPL +993 -0
  76. data/vendor/libgit2/deps/winhttp/COPYING.LGPL +502 -0
  77. data/vendor/libgit2/deps/zlib/CMakeLists.txt +1 -0
  78. data/vendor/libgit2/deps/zlib/COPYING +27 -0
  79. data/vendor/libgit2/deps/zlib/adler32.c +0 -7
  80. data/vendor/libgit2/deps/zlib/crc32.c +0 -7
  81. data/vendor/libgit2/include/git2/annotated_commit.h +9 -0
  82. data/vendor/libgit2/include/git2/apply.h +149 -0
  83. data/vendor/libgit2/include/git2/attr.h +20 -13
  84. data/vendor/libgit2/include/git2/blame.h +4 -4
  85. data/vendor/libgit2/include/git2/blob.h +44 -12
  86. data/vendor/libgit2/include/git2/buffer.h +20 -26
  87. data/vendor/libgit2/include/git2/cert.h +135 -0
  88. data/vendor/libgit2/include/git2/checkout.h +53 -21
  89. data/vendor/libgit2/include/git2/cherrypick.h +3 -3
  90. data/vendor/libgit2/include/git2/clone.h +5 -5
  91. data/vendor/libgit2/include/git2/commit.h +25 -3
  92. data/vendor/libgit2/include/git2/common.h +35 -10
  93. data/vendor/libgit2/include/git2/config.h +29 -19
  94. data/vendor/libgit2/include/git2/cred.h +308 -0
  95. data/vendor/libgit2/include/git2/deprecated.h +493 -0
  96. data/vendor/libgit2/include/git2/describe.h +4 -4
  97. data/vendor/libgit2/include/git2/diff.h +177 -135
  98. data/vendor/libgit2/include/git2/errors.h +53 -46
  99. data/vendor/libgit2/include/git2/filter.h +8 -0
  100. data/vendor/libgit2/include/git2/index.h +74 -52
  101. data/vendor/libgit2/include/git2/indexer.h +76 -6
  102. data/vendor/libgit2/include/git2/merge.h +25 -10
  103. data/vendor/libgit2/include/git2/net.h +0 -5
  104. data/vendor/libgit2/include/git2/notes.h +1 -1
  105. data/vendor/libgit2/include/git2/object.h +17 -29
  106. data/vendor/libgit2/include/git2/odb.h +12 -11
  107. data/vendor/libgit2/include/git2/odb_backend.h +10 -9
  108. data/vendor/libgit2/include/git2/oid.h +2 -2
  109. data/vendor/libgit2/include/git2/pack.h +14 -3
  110. data/vendor/libgit2/include/git2/proxy.h +5 -3
  111. data/vendor/libgit2/include/git2/rebase.h +46 -2
  112. data/vendor/libgit2/include/git2/refs.h +34 -16
  113. data/vendor/libgit2/include/git2/remote.h +111 -14
  114. data/vendor/libgit2/include/git2/repository.h +69 -34
  115. data/vendor/libgit2/include/git2/revert.h +1 -1
  116. data/vendor/libgit2/include/git2/revwalk.h +7 -7
  117. data/vendor/libgit2/include/git2/signature.h +2 -2
  118. data/vendor/libgit2/include/git2/stash.h +5 -5
  119. data/vendor/libgit2/include/git2/status.h +26 -17
  120. data/vendor/libgit2/include/git2/submodule.h +23 -6
  121. data/vendor/libgit2/include/git2/sys/alloc.h +18 -18
  122. data/vendor/libgit2/include/git2/sys/commit.h +1 -1
  123. data/vendor/libgit2/include/git2/sys/config.h +13 -13
  124. data/vendor/libgit2/include/git2/sys/cred.h +90 -0
  125. data/vendor/libgit2/include/git2/sys/filter.h +6 -6
  126. data/vendor/libgit2/include/git2/sys/merge.h +3 -3
  127. data/vendor/libgit2/include/git2/sys/odb_backend.h +66 -22
  128. data/vendor/libgit2/include/git2/sys/path.h +14 -5
  129. data/vendor/libgit2/include/git2/sys/refdb_backend.h +76 -40
  130. data/vendor/libgit2/include/git2/sys/repository.h +5 -1
  131. data/vendor/libgit2/include/git2/sys/stream.h +92 -12
  132. data/vendor/libgit2/include/git2/sys/transport.h +129 -83
  133. data/vendor/libgit2/include/git2/tag.h +13 -4
  134. data/vendor/libgit2/include/git2/trace.h +2 -2
  135. data/vendor/libgit2/include/git2/transport.h +11 -311
  136. data/vendor/libgit2/include/git2/tree.h +4 -4
  137. data/vendor/libgit2/include/git2/types.h +25 -106
  138. data/vendor/libgit2/include/git2/version.h +3 -3
  139. data/vendor/libgit2/include/git2/worktree.h +5 -5
  140. data/vendor/libgit2/include/git2.h +4 -0
  141. data/vendor/libgit2/src/CMakeLists.txt +104 -235
  142. data/vendor/libgit2/src/alloc.c +14 -18
  143. data/vendor/libgit2/src/{stdalloc.c → allocators/stdalloc.c} +7 -8
  144. data/vendor/libgit2/src/{stdalloc.h → allocators/stdalloc.h} +4 -4
  145. data/vendor/libgit2/src/allocators/win32_crtdbg.c +118 -0
  146. data/vendor/libgit2/src/{transports/cred.h → allocators/win32_crtdbg.h} +5 -4
  147. data/vendor/libgit2/src/annotated_commit.c +18 -11
  148. data/vendor/libgit2/src/apply.c +535 -28
  149. data/vendor/libgit2/src/apply.h +3 -1
  150. data/vendor/libgit2/src/array.h +2 -2
  151. data/vendor/libgit2/src/attr.c +77 -71
  152. data/vendor/libgit2/src/attr_file.c +203 -117
  153. data/vendor/libgit2/src/attr_file.h +9 -9
  154. data/vendor/libgit2/src/attrcache.c +49 -51
  155. data/vendor/libgit2/src/attrcache.h +2 -1
  156. data/vendor/libgit2/src/blame.c +38 -18
  157. data/vendor/libgit2/src/blame.h +1 -1
  158. data/vendor/libgit2/src/blame_git.c +29 -15
  159. data/vendor/libgit2/src/blob.c +123 -37
  160. data/vendor/libgit2/src/blob.h +19 -2
  161. data/vendor/libgit2/src/branch.c +47 -23
  162. data/vendor/libgit2/src/buf_text.c +7 -6
  163. data/vendor/libgit2/src/buffer.c +60 -53
  164. data/vendor/libgit2/src/cache.c +38 -45
  165. data/vendor/libgit2/src/cache.h +3 -3
  166. data/vendor/libgit2/src/cc-compat.h +20 -3
  167. data/vendor/libgit2/src/checkout.c +77 -67
  168. data/vendor/libgit2/src/cherrypick.c +12 -6
  169. data/vendor/libgit2/src/clone.c +36 -14
  170. data/vendor/libgit2/src/clone.h +4 -0
  171. data/vendor/libgit2/src/commit.c +103 -48
  172. data/vendor/libgit2/src/commit.h +7 -0
  173. data/vendor/libgit2/src/commit_list.c +36 -78
  174. data/vendor/libgit2/src/commit_list.h +2 -2
  175. data/vendor/libgit2/src/common.h +24 -90
  176. data/vendor/libgit2/src/config.c +203 -176
  177. data/vendor/libgit2/src/config.h +8 -20
  178. data/vendor/libgit2/src/config_backend.h +96 -0
  179. data/vendor/libgit2/src/config_cache.c +41 -35
  180. data/vendor/libgit2/src/config_entries.c +229 -0
  181. data/vendor/libgit2/src/config_entries.h +24 -0
  182. data/vendor/libgit2/src/config_file.c +422 -680
  183. data/vendor/libgit2/src/config_mem.c +220 -0
  184. data/vendor/libgit2/src/config_parse.c +96 -68
  185. data/vendor/libgit2/src/config_parse.h +15 -14
  186. data/vendor/libgit2/src/config_snapshot.c +206 -0
  187. data/vendor/libgit2/src/crlf.c +219 -196
  188. data/vendor/libgit2/src/delta.c +25 -18
  189. data/vendor/libgit2/src/describe.c +42 -41
  190. data/vendor/libgit2/src/diff.c +52 -67
  191. data/vendor/libgit2/src/diff.h +2 -1
  192. data/vendor/libgit2/src/diff_driver.c +44 -46
  193. data/vendor/libgit2/src/diff_file.c +16 -14
  194. data/vendor/libgit2/src/diff_file.h +1 -1
  195. data/vendor/libgit2/src/diff_generate.c +158 -103
  196. data/vendor/libgit2/src/diff_generate.h +3 -3
  197. data/vendor/libgit2/src/diff_parse.c +4 -4
  198. data/vendor/libgit2/src/diff_print.c +34 -22
  199. data/vendor/libgit2/src/diff_stats.c +22 -7
  200. data/vendor/libgit2/src/diff_tform.c +18 -16
  201. data/vendor/libgit2/src/diff_xdiff.c +3 -3
  202. data/vendor/libgit2/src/errors.c +51 -39
  203. data/vendor/libgit2/src/errors.h +81 -0
  204. data/vendor/libgit2/src/features.h.in +9 -3
  205. data/vendor/libgit2/src/fetch.c +8 -3
  206. data/vendor/libgit2/src/fetchhead.c +12 -12
  207. data/vendor/libgit2/src/filebuf.c +28 -32
  208. data/vendor/libgit2/src/filebuf.h +2 -2
  209. data/vendor/libgit2/src/filter.c +47 -33
  210. data/vendor/libgit2/src/filter.h +0 -10
  211. data/vendor/libgit2/src/{fileops.c → futils.c} +70 -63
  212. data/vendor/libgit2/src/{fileops.h → futils.h} +6 -6
  213. data/vendor/libgit2/src/global.c +35 -55
  214. data/vendor/libgit2/src/global.h +0 -2
  215. data/vendor/libgit2/src/hash/sha1/collisiondetect.c +48 -0
  216. data/vendor/libgit2/src/hash/sha1/collisiondetect.h +19 -0
  217. data/vendor/libgit2/src/hash/{hash_common_crypto.h → sha1/common_crypto.c} +17 -17
  218. data/vendor/libgit2/src/hash/sha1/common_crypto.h +19 -0
  219. data/vendor/libgit2/src/hash/{hash_generic.c → sha1/generic.c} +22 -10
  220. data/vendor/libgit2/src/hash/{hash_generic.h → sha1/generic.h} +4 -10
  221. data/vendor/libgit2/src/hash/{hash_mbedtls.c → sha1/mbedtls.c} +15 -7
  222. data/vendor/libgit2/src/hash/{hash_mbedtls.h → sha1/mbedtls.h} +6 -7
  223. data/vendor/libgit2/src/hash/sha1/openssl.c +59 -0
  224. data/vendor/libgit2/src/hash/sha1/openssl.h +19 -0
  225. data/vendor/libgit2/src/hash/{sha1dc → sha1/sha1dc}/sha1.c +14 -3
  226. data/vendor/libgit2/src/hash/{hash_win32.c → sha1/win32.c} +47 -37
  227. data/vendor/libgit2/src/hash/{hash_win32.h → sha1/win32.h} +6 -19
  228. data/vendor/libgit2/src/hash/sha1.h +38 -0
  229. data/vendor/libgit2/src/hash.c +61 -0
  230. data/vendor/libgit2/src/hash.h +20 -21
  231. data/vendor/libgit2/src/hashsig.c +5 -5
  232. data/vendor/libgit2/src/idxmap.c +107 -61
  233. data/vendor/libgit2/src/idxmap.h +153 -31
  234. data/vendor/libgit2/src/ignore.c +38 -42
  235. data/vendor/libgit2/src/index.c +264 -199
  236. data/vendor/libgit2/src/index.h +7 -1
  237. data/vendor/libgit2/src/indexer.c +338 -167
  238. data/vendor/libgit2/src/integer.h +71 -26
  239. data/vendor/libgit2/src/iterator.c +134 -62
  240. data/vendor/libgit2/src/iterator.h +15 -0
  241. data/vendor/libgit2/src/mailmap.c +8 -8
  242. data/vendor/libgit2/src/map.h +1 -1
  243. data/vendor/libgit2/src/merge.c +137 -93
  244. data/vendor/libgit2/src/merge_driver.c +11 -11
  245. data/vendor/libgit2/src/merge_file.c +2 -2
  246. data/vendor/libgit2/src/mwindow.c +24 -29
  247. data/vendor/libgit2/src/mwindow.h +4 -4
  248. data/vendor/libgit2/src/net.c +184 -0
  249. data/vendor/libgit2/src/net.h +36 -0
  250. data/vendor/libgit2/src/netops.c +55 -156
  251. data/vendor/libgit2/src/netops.h +3 -23
  252. data/vendor/libgit2/src/notes.c +14 -9
  253. data/vendor/libgit2/src/object.c +120 -69
  254. data/vendor/libgit2/src/object.h +22 -9
  255. data/vendor/libgit2/src/object_api.c +8 -8
  256. data/vendor/libgit2/src/odb.c +111 -88
  257. data/vendor/libgit2/src/odb.h +8 -7
  258. data/vendor/libgit2/src/odb_loose.c +58 -47
  259. data/vendor/libgit2/src/odb_mempack.c +21 -34
  260. data/vendor/libgit2/src/odb_pack.c +17 -13
  261. data/vendor/libgit2/src/offmap.c +53 -35
  262. data/vendor/libgit2/src/offmap.h +108 -21
  263. data/vendor/libgit2/src/oid.c +12 -7
  264. data/vendor/libgit2/src/oidmap.c +49 -47
  265. data/vendor/libgit2/src/oidmap.h +101 -24
  266. data/vendor/libgit2/src/pack-objects.c +87 -86
  267. data/vendor/libgit2/src/pack-objects.h +2 -8
  268. data/vendor/libgit2/src/pack.c +94 -96
  269. data/vendor/libgit2/src/pack.h +16 -18
  270. data/vendor/libgit2/src/parse.c +17 -4
  271. data/vendor/libgit2/src/parse.h +3 -3
  272. data/vendor/libgit2/src/patch.c +3 -3
  273. data/vendor/libgit2/src/patch_generate.c +18 -18
  274. data/vendor/libgit2/src/patch_parse.c +147 -79
  275. data/vendor/libgit2/src/path.c +207 -62
  276. data/vendor/libgit2/src/path.h +14 -0
  277. data/vendor/libgit2/src/pathspec.c +18 -18
  278. data/vendor/libgit2/src/pool.c +26 -22
  279. data/vendor/libgit2/src/pool.h +7 -7
  280. data/vendor/libgit2/src/posix.c +10 -10
  281. data/vendor/libgit2/src/posix.h +12 -1
  282. data/vendor/libgit2/src/proxy.c +8 -3
  283. data/vendor/libgit2/src/push.c +35 -29
  284. data/vendor/libgit2/src/push.h +2 -1
  285. data/vendor/libgit2/src/reader.c +265 -0
  286. data/vendor/libgit2/src/reader.h +107 -0
  287. data/vendor/libgit2/src/rebase.c +97 -38
  288. data/vendor/libgit2/src/refdb.c +15 -3
  289. data/vendor/libgit2/src/refdb_fs.c +318 -222
  290. data/vendor/libgit2/src/reflog.c +13 -15
  291. data/vendor/libgit2/src/refs.c +122 -89
  292. data/vendor/libgit2/src/refs.h +5 -3
  293. data/vendor/libgit2/src/refspec.c +27 -33
  294. data/vendor/libgit2/src/regexp.c +221 -0
  295. data/vendor/libgit2/src/regexp.h +97 -0
  296. data/vendor/libgit2/src/remote.c +229 -178
  297. data/vendor/libgit2/src/remote.h +11 -2
  298. data/vendor/libgit2/src/repository.c +227 -172
  299. data/vendor/libgit2/src/repository.h +52 -40
  300. data/vendor/libgit2/src/reset.c +7 -7
  301. data/vendor/libgit2/src/revert.c +11 -6
  302. data/vendor/libgit2/src/revparse.c +46 -46
  303. data/vendor/libgit2/src/revwalk.c +89 -54
  304. data/vendor/libgit2/src/revwalk.h +20 -0
  305. data/vendor/libgit2/src/settings.c +22 -9
  306. data/vendor/libgit2/src/signature.c +15 -13
  307. data/vendor/libgit2/src/sortedcache.c +22 -36
  308. data/vendor/libgit2/src/sortedcache.h +1 -1
  309. data/vendor/libgit2/src/stash.c +56 -76
  310. data/vendor/libgit2/src/status.c +27 -21
  311. data/vendor/libgit2/src/stream.h +17 -2
  312. data/vendor/libgit2/src/streams/mbedtls.c +100 -80
  313. data/vendor/libgit2/src/streams/mbedtls.h +5 -2
  314. data/vendor/libgit2/src/streams/openssl.c +93 -81
  315. data/vendor/libgit2/src/streams/openssl.h +5 -2
  316. data/vendor/libgit2/src/streams/registry.c +118 -0
  317. data/vendor/libgit2/src/streams/registry.h +19 -0
  318. data/vendor/libgit2/src/streams/socket.c +55 -30
  319. data/vendor/libgit2/src/streams/stransport.c +57 -32
  320. data/vendor/libgit2/src/streams/stransport.h +5 -0
  321. data/vendor/libgit2/src/streams/tls.c +48 -20
  322. data/vendor/libgit2/src/streams/tls.h +12 -4
  323. data/vendor/libgit2/src/strmap.c +47 -74
  324. data/vendor/libgit2/src/strmap.h +108 -33
  325. data/vendor/libgit2/src/submodule.c +190 -169
  326. data/vendor/libgit2/src/submodule.h +1 -1
  327. data/vendor/libgit2/src/sysdir.c +25 -15
  328. data/vendor/libgit2/src/tag.c +39 -26
  329. data/vendor/libgit2/src/tag.h +2 -1
  330. data/vendor/libgit2/src/trace.c +2 -2
  331. data/vendor/libgit2/src/trace.h +2 -2
  332. data/vendor/libgit2/src/trailer.c +46 -32
  333. data/vendor/libgit2/src/transaction.c +30 -29
  334. data/vendor/libgit2/src/transport.c +3 -3
  335. data/vendor/libgit2/src/transports/auth.c +14 -10
  336. data/vendor/libgit2/src/transports/auth.h +10 -3
  337. data/vendor/libgit2/src/transports/auth_negotiate.c +31 -16
  338. data/vendor/libgit2/src/transports/auth_negotiate.h +2 -2
  339. data/vendor/libgit2/src/transports/auth_ntlm.c +223 -0
  340. data/vendor/libgit2/src/transports/auth_ntlm.h +35 -0
  341. data/vendor/libgit2/src/transports/cred.c +24 -24
  342. data/vendor/libgit2/src/transports/git.c +25 -30
  343. data/vendor/libgit2/src/transports/http.c +871 -335
  344. data/vendor/libgit2/src/transports/http.h +2 -0
  345. data/vendor/libgit2/src/transports/local.c +28 -28
  346. data/vendor/libgit2/src/transports/smart.c +64 -46
  347. data/vendor/libgit2/src/transports/smart.h +5 -6
  348. data/vendor/libgit2/src/transports/smart_pkt.c +162 -151
  349. data/vendor/libgit2/src/transports/smart_protocol.c +64 -94
  350. data/vendor/libgit2/src/transports/ssh.c +76 -65
  351. data/vendor/libgit2/src/transports/winhttp.c +328 -319
  352. data/vendor/libgit2/src/tree-cache.c +21 -14
  353. data/vendor/libgit2/src/tree.c +119 -112
  354. data/vendor/libgit2/src/tree.h +1 -0
  355. data/vendor/libgit2/src/unix/map.c +3 -3
  356. data/vendor/libgit2/src/unix/posix.h +1 -11
  357. data/vendor/libgit2/src/userdiff.h +3 -1
  358. data/vendor/libgit2/src/util.c +154 -93
  359. data/vendor/libgit2/src/util.h +19 -23
  360. data/vendor/libgit2/src/vector.c +15 -10
  361. data/vendor/libgit2/src/wildmatch.c +320 -0
  362. data/vendor/libgit2/src/wildmatch.h +23 -0
  363. data/vendor/libgit2/src/win32/dir.c +3 -3
  364. data/vendor/libgit2/src/win32/findfile.c +1 -1
  365. data/vendor/libgit2/src/win32/map.c +9 -11
  366. data/vendor/libgit2/src/win32/msvc-compat.h +6 -0
  367. data/vendor/libgit2/src/win32/path_w32.c +113 -9
  368. data/vendor/libgit2/src/win32/path_w32.h +18 -29
  369. data/vendor/libgit2/src/win32/posix.h +1 -4
  370. data/vendor/libgit2/src/win32/posix_w32.c +69 -44
  371. data/vendor/libgit2/src/win32/precompiled.h +0 -2
  372. data/vendor/libgit2/src/win32/thread.c +5 -10
  373. data/vendor/libgit2/src/win32/w32_buffer.c +9 -5
  374. data/vendor/libgit2/src/win32/w32_common.h +39 -0
  375. data/vendor/libgit2/src/win32/w32_crtdbg_stacktrace.c +2 -95
  376. data/vendor/libgit2/src/win32/w32_crtdbg_stacktrace.h +0 -2
  377. data/vendor/libgit2/src/win32/w32_stack.c +6 -11
  378. data/vendor/libgit2/src/win32/w32_stack.h +3 -3
  379. data/vendor/libgit2/src/win32/w32_util.c +27 -64
  380. data/vendor/libgit2/src/win32/w32_util.h +5 -49
  381. data/vendor/libgit2/src/worktree.c +44 -30
  382. data/vendor/libgit2/src/xdiff/xdiffi.c +5 -5
  383. data/vendor/libgit2/src/xdiff/xhistogram.c +1 -1
  384. data/vendor/libgit2/src/xdiff/xmerge.c +27 -15
  385. data/vendor/libgit2/src/xdiff/xpatience.c +3 -0
  386. data/vendor/libgit2/src/zstream.c +4 -4
  387. metadata +115 -38
  388. data/vendor/libgit2/deps/regex/CMakeLists.txt +0 -2
  389. data/vendor/libgit2/deps/regex/config.h +0 -7
  390. data/vendor/libgit2/deps/regex/regcomp.c +0 -3857
  391. data/vendor/libgit2/deps/regex/regex.c +0 -92
  392. data/vendor/libgit2/deps/regex/regex.h +0 -582
  393. data/vendor/libgit2/deps/regex/regex_internal.c +0 -1744
  394. data/vendor/libgit2/deps/regex/regex_internal.h +0 -819
  395. data/vendor/libgit2/deps/regex/regexec.c +0 -4369
  396. data/vendor/libgit2/include/git2/inttypes.h +0 -309
  397. data/vendor/libgit2/include/git2/sys/time.h +0 -31
  398. data/vendor/libgit2/libgit2.pc.in +0 -13
  399. data/vendor/libgit2/src/config_file.h +0 -73
  400. data/vendor/libgit2/src/fnmatch.c +0 -248
  401. data/vendor/libgit2/src/fnmatch.h +0 -48
  402. data/vendor/libgit2/src/hash/hash_collisiondetect.h +0 -47
  403. data/vendor/libgit2/src/hash/hash_openssl.h +0 -59
  404. data/vendor/libgit2/src/streams/curl.c +0 -385
  405. data/vendor/libgit2/src/streams/curl.h +0 -17
  406. /data/vendor/libgit2/deps/http-parser/{LICENSE-MIT → COPYING} +0 -0
  407. /data/vendor/libgit2/src/hash/{sha1dc → sha1/sha1dc}/sha1.h +0 -0
  408. /data/vendor/libgit2/src/hash/{sha1dc → sha1/sha1dc}/ubc_check.c +0 -0
  409. /data/vendor/libgit2/src/hash/{sha1dc → sha1/sha1dc}/ubc_check.h +0 -0
@@ -5,54 +5,37 @@
5
5
  * a Linking Exception. For full terms see the included COPYING file.
6
6
  */
7
7
 
8
- #include "config_file.h"
9
-
10
8
  #include "config.h"
11
- #include "filebuf.h"
12
- #include "sysdir.h"
13
- #include "buffer.h"
14
- #include "buf_text.h"
9
+
15
10
  #include "git2/config.h"
16
11
  #include "git2/sys/config.h"
17
- #include "git2/types.h"
18
- #include "strmap.h"
12
+
19
13
  #include "array.h"
14
+ #include "buffer.h"
15
+ #include "config_backend.h"
16
+ #include "config_entries.h"
20
17
  #include "config_parse.h"
21
-
22
- #include <ctype.h>
23
- #include <sys/types.h>
24
- #include <regex.h>
25
-
26
- typedef struct config_entry_list {
27
- struct config_entry_list *next;
28
- git_config_entry *entry;
29
- } config_entry_list;
30
-
31
- typedef struct git_config_file_iter {
32
- git_config_iterator parent;
33
- config_entry_list *head;
34
- } git_config_file_iter;
18
+ #include "filebuf.h"
19
+ #include "regexp.h"
20
+ #include "sysdir.h"
21
+ #include "wildmatch.h"
35
22
 
36
23
  /* Max depth for [include] directives */
37
24
  #define MAX_INCLUDE_DEPTH 10
38
25
 
39
- typedef struct {
40
- git_atomic refcount;
41
- git_strmap *map;
42
- config_entry_list *list;
43
- } diskfile_entries;
26
+ typedef struct config_file {
27
+ git_futils_filestamp stamp;
28
+ git_oid checksum;
29
+ char *path;
30
+ git_array_t(struct config_file) includes;
31
+ } config_file;
44
32
 
45
33
  typedef struct {
46
34
  git_config_backend parent;
47
- /* mutex to coordinate accessing the values */
48
35
  git_mutex values_mutex;
49
- diskfile_entries *entries;
36
+ git_config_entries *entries;
50
37
  const git_repository *repo;
51
38
  git_config_level_t level;
52
- } diskfile_header;
53
-
54
- typedef struct {
55
- diskfile_header header;
56
39
 
57
40
  git_array_t(git_config_parser) readers;
58
41
 
@@ -60,184 +43,47 @@ typedef struct {
60
43
  git_filebuf locked_buf;
61
44
  git_buf locked_content;
62
45
 
63
- struct config_file file;
64
- } diskfile_backend;
65
-
66
- typedef struct {
67
- diskfile_header header;
68
-
69
- diskfile_backend *snapshot_from;
70
- } diskfile_readonly_backend;
46
+ config_file file;
47
+ } config_file_backend;
71
48
 
72
49
  typedef struct {
73
50
  const git_repository *repo;
74
- const char *file_path;
75
- diskfile_entries *entries;
51
+ config_file *file;
52
+ git_config_entries *entries;
76
53
  git_config_level_t level;
77
54
  unsigned int depth;
78
- } diskfile_parse_state;
55
+ } config_file_parse_data;
79
56
 
80
- static int config_read(diskfile_entries *entries, const git_repository *repo, git_config_file *file, git_config_level_t level, int depth);
81
- static int config_write(diskfile_backend *cfg, const char *orig_key, const char *key, const regex_t *preg, const char *value);
57
+ static int config_file_read(git_config_entries *entries, const git_repository *repo, config_file *file, git_config_level_t level, int depth);
58
+ static int config_file_read_buffer(git_config_entries *entries, const git_repository *repo, config_file *file, git_config_level_t level, int depth, const char *buf, size_t buflen);
59
+ static int config_file_write(config_file_backend *cfg, const char *orig_key, const char *key, const git_regexp *preg, const char *value);
82
60
  static char *escape_value(const char *ptr);
83
61
 
84
- int git_config_file__snapshot(git_config_backend **out, diskfile_backend *in);
85
- static int config_snapshot(git_config_backend **out, git_config_backend *in);
86
-
87
- static int config_error_readonly(void)
88
- {
89
- giterr_set(GITERR_CONFIG, "this backend is read-only");
90
- return -1;
91
- }
92
-
93
- static void config_entry_list_free(config_entry_list *list)
94
- {
95
- config_entry_list *next;
96
-
97
- while (list != NULL) {
98
- next = list->next;
99
-
100
- git__free((char*) list->entry->name);
101
- git__free((char *) list->entry->value);
102
- git__free(list->entry);
103
- git__free(list);
104
-
105
- list = next;
106
- };
107
- }
108
-
109
- int git_config_file_normalize_section(char *start, char *end)
110
- {
111
- char *scan;
112
-
113
- if (start == end)
114
- return GIT_EINVALIDSPEC;
115
-
116
- /* Validate and downcase range */
117
- for (scan = start; *scan; ++scan) {
118
- if (end && scan >= end)
119
- break;
120
- if (isalnum(*scan))
121
- *scan = (char)git__tolower(*scan);
122
- else if (*scan != '-' || scan == start)
123
- return GIT_EINVALIDSPEC;
124
- }
125
-
126
- if (scan == start)
127
- return GIT_EINVALIDSPEC;
128
-
129
- return 0;
130
- }
131
-
132
- static void config_entry_list_append(config_entry_list **list, config_entry_list *entry)
133
- {
134
- config_entry_list *head = *list;
135
-
136
- if (head) {
137
- while (head->next != NULL)
138
- head = head->next;
139
- head->next = entry;
140
- } else {
141
- *list = entry;
142
- }
143
- }
144
-
145
- /* Add or append the new config option */
146
- static int diskfile_entries_append(diskfile_entries *entries, git_config_entry *entry)
147
- {
148
- git_strmap_iter pos;
149
- config_entry_list *existing, *var;
150
- int error = 0;
151
-
152
- var = git__calloc(1, sizeof(config_entry_list));
153
- GITERR_CHECK_ALLOC(var);
154
- var->entry = entry;
155
-
156
- pos = git_strmap_lookup_index(entries->map, entry->name);
157
- if (!git_strmap_valid_index(entries->map, pos)) {
158
- git_strmap_insert(entries->map, entry->name, var, &error);
159
-
160
- if (error > 0)
161
- error = 0;
162
- } else {
163
- existing = git_strmap_value_at(entries->map, pos);
164
- config_entry_list_append(&existing, var);
165
- }
166
-
167
- var = git__calloc(1, sizeof(config_entry_list));
168
- GITERR_CHECK_ALLOC(var);
169
- var->entry = entry;
170
- config_entry_list_append(&entries->list, var);
171
-
172
- return error;
173
- }
174
-
175
- static void diskfile_entries_free(diskfile_entries *entries)
176
- {
177
- config_entry_list *list = NULL, *next;
178
-
179
- if (!entries)
180
- return;
181
-
182
- if (git_atomic_dec(&entries->refcount) != 0)
183
- return;
184
-
185
- git_strmap_foreach_value(entries->map, list, config_entry_list_free(list));
186
- git_strmap_free(entries->map);
187
-
188
- list = entries->list;
189
- while (list != NULL) {
190
- next = list->next;
191
- git__free(list);
192
- list = next;
193
- }
194
-
195
- git__free(entries);
196
- }
197
-
198
62
  /**
199
63
  * Take the current values map from the backend and increase its
200
64
  * refcount. This is its own function to make sure we use the mutex to
201
65
  * avoid the map pointer from changing under us.
202
66
  */
203
- static diskfile_entries *diskfile_entries_take(diskfile_header *h)
67
+ static int config_file_entries_take(git_config_entries **out, config_file_backend *b)
204
68
  {
205
- diskfile_entries *entries;
206
-
207
- if (git_mutex_lock(&h->values_mutex) < 0) {
208
- giterr_set(GITERR_OS, "failed to lock config backend");
209
- return NULL;
210
- }
211
-
212
- entries = h->entries;
213
- git_atomic_inc(&entries->refcount);
214
-
215
- git_mutex_unlock(&h->values_mutex);
216
-
217
- return entries;
218
- }
219
-
220
- static int diskfile_entries_alloc(diskfile_entries **out)
221
- {
222
- diskfile_entries *entries;
223
69
  int error;
224
70
 
225
- entries = git__calloc(1, sizeof(diskfile_entries));
226
- GITERR_CHECK_ALLOC(entries);
71
+ if ((error = git_mutex_lock(&b->values_mutex)) < 0) {
72
+ git_error_set(GIT_ERROR_OS, "failed to lock config backend");
73
+ return error;
74
+ }
227
75
 
228
- git_atomic_set(&entries->refcount, 1);
76
+ git_config_entries_incref(b->entries);
77
+ *out = b->entries;
229
78
 
230
- if ((error = git_strmap_alloc(&entries->map)) < 0)
231
- git__free(entries);
232
- else
233
- *out = entries;
79
+ git_mutex_unlock(&b->values_mutex);
234
80
 
235
- return error;
81
+ return 0;
236
82
  }
237
83
 
238
- static void config_file_clear(struct config_file *file)
84
+ static void config_file_clear(config_file *file)
239
85
  {
240
- struct config_file *include;
86
+ config_file *include;
241
87
  uint32_t i;
242
88
 
243
89
  if (file == NULL)
@@ -251,31 +97,31 @@ static void config_file_clear(struct config_file *file)
251
97
  git__free(file->path);
252
98
  }
253
99
 
254
- static int config_open(git_config_backend *cfg, git_config_level_t level, const git_repository *repo)
100
+ static int config_file_open(git_config_backend *cfg, git_config_level_t level, const git_repository *repo)
255
101
  {
102
+ config_file_backend *b = GIT_CONTAINER_OF(cfg, config_file_backend, parent);
256
103
  int res;
257
- diskfile_backend *b = (diskfile_backend *)cfg;
258
104
 
259
- b->header.level = level;
260
- b->header.repo = repo;
105
+ b->level = level;
106
+ b->repo = repo;
261
107
 
262
- if ((res = diskfile_entries_alloc(&b->header.entries)) < 0)
108
+ if ((res = git_config_entries_new(&b->entries)) < 0)
263
109
  return res;
264
110
 
265
111
  if (!git_path_exists(b->file.path))
266
112
  return 0;
267
113
 
268
- if (res < 0 || (res = config_read(b->header.entries, repo, &b->file, level, 0)) < 0) {
269
- diskfile_entries_free(b->header.entries);
270
- b->header.entries = NULL;
114
+ if (res < 0 || (res = config_file_read(b->entries, repo, &b->file, level, 0)) < 0) {
115
+ git_config_entries_free(b->entries);
116
+ b->entries = NULL;
271
117
  }
272
118
 
273
119
  return res;
274
120
  }
275
121
 
276
- static int config_is_modified(int *modified, struct config_file *file)
122
+ static int config_file_is_modified(int *modified, config_file *file)
277
123
  {
278
- git_config_file *include;
124
+ config_file *include;
279
125
  git_buf buf = GIT_BUF_INIT;
280
126
  git_oid hash;
281
127
  uint32_t i;
@@ -283,6 +129,9 @@ static int config_is_modified(int *modified, struct config_file *file)
283
129
 
284
130
  *modified = 0;
285
131
 
132
+ if (!git_futils_filestamp_check(&file->stamp, file->path))
133
+ goto check_includes;
134
+
286
135
  if ((error = git_futils_readbuffer(&buf, file->path)) < 0)
287
136
  goto out;
288
137
 
@@ -294,8 +143,9 @@ static int config_is_modified(int *modified, struct config_file *file)
294
143
  goto out;
295
144
  }
296
145
 
146
+ check_includes:
297
147
  git_array_foreach(file->includes, i, include) {
298
- if ((error = config_is_modified(modified, include)) < 0 || *modified)
148
+ if ((error = config_file_is_modified(modified, include)) < 0 || *modified)
299
149
  goto out;
300
150
  }
301
151
 
@@ -305,362 +155,293 @@ out:
305
155
  return error;
306
156
  }
307
157
 
308
- static int config_refresh(git_config_backend *cfg)
158
+ static int config_file_set_entries(git_config_backend *cfg, git_config_entries *entries)
309
159
  {
310
- diskfile_backend *b = (diskfile_backend *)cfg;
311
- diskfile_entries *entries = NULL, *tmp;
312
- git_config_file *include;
313
- int error, modified;
160
+ config_file_backend *b = GIT_CONTAINER_OF(cfg, config_file_backend, parent);
161
+ git_config_entries *old = NULL;
162
+ config_file *include;
163
+ int error;
314
164
  uint32_t i;
315
165
 
316
- if (b->header.parent.readonly)
317
- return config_error_readonly();
166
+ if (b->parent.readonly) {
167
+ git_error_set(GIT_ERROR_CONFIG, "this backend is read-only");
168
+ return -1;
169
+ }
318
170
 
319
- error = config_is_modified(&modified, &b->file);
320
- if (error < 0 && error != GIT_ENOTFOUND)
171
+ git_array_foreach(b->file.includes, i, include)
172
+ config_file_clear(include);
173
+ git_array_clear(b->file.includes);
174
+
175
+ if ((error = git_mutex_lock(&b->values_mutex)) < 0) {
176
+ git_error_set(GIT_ERROR_OS, "failed to lock config backend");
321
177
  goto out;
178
+ }
322
179
 
323
- if (!modified)
324
- return 0;
180
+ old = b->entries;
181
+ b->entries = entries;
325
182
 
326
- if ((error = diskfile_entries_alloc(&entries)) < 0)
327
- goto out;
183
+ git_mutex_unlock(&b->values_mutex);
328
184
 
329
- /* Reparse the current configuration */
330
- git_array_foreach(b->file.includes, i, include) {
331
- config_file_clear(include);
332
- }
333
- git_array_clear(b->file.includes);
185
+ out:
186
+ git_config_entries_free(old);
187
+ return error;
188
+ }
334
189
 
335
- if ((error = config_read(entries, b->header.repo, &b->file, b->header.level, 0)) < 0)
190
+ static int config_file_refresh_from_buffer(git_config_backend *cfg, const char *buf, size_t buflen)
191
+ {
192
+ config_file_backend *b = GIT_CONTAINER_OF(cfg, config_file_backend, parent);
193
+ git_config_entries *entries = NULL;
194
+ int error;
195
+
196
+ if ((error = git_config_entries_new(&entries)) < 0 ||
197
+ (error = config_file_read_buffer(entries, b->repo, &b->file,
198
+ b->level, 0, buf, buflen)) < 0 ||
199
+ (error = config_file_set_entries(cfg, entries)) < 0)
336
200
  goto out;
337
201
 
338
- if ((error = git_mutex_lock(&b->header.values_mutex)) < 0) {
339
- giterr_set(GITERR_OS, "failed to lock config backend");
202
+ entries = NULL;
203
+ out:
204
+ git_config_entries_free(entries);
205
+ return error;
206
+ }
207
+
208
+ static int config_file_refresh(git_config_backend *cfg)
209
+ {
210
+ config_file_backend *b = GIT_CONTAINER_OF(cfg, config_file_backend, parent);
211
+ git_config_entries *entries = NULL;
212
+ int error, modified;
213
+
214
+ if (cfg->readonly)
215
+ return 0;
216
+
217
+ if ((error = config_file_is_modified(&modified, &b->file)) < 0 && error != GIT_ENOTFOUND)
340
218
  goto out;
341
- }
342
219
 
343
- tmp = b->header.entries;
344
- b->header.entries = entries;
345
- entries = tmp;
220
+ if (!modified)
221
+ return 0;
346
222
 
347
- git_mutex_unlock(&b->header.values_mutex);
223
+ if ((error = git_config_entries_new(&entries)) < 0 ||
224
+ (error = config_file_read(entries, b->repo, &b->file, b->level, 0)) < 0 ||
225
+ (error = config_file_set_entries(cfg, entries)) < 0)
226
+ goto out;
348
227
 
228
+ entries = NULL;
349
229
  out:
350
- diskfile_entries_free(entries);
230
+ git_config_entries_free(entries);
351
231
 
352
232
  return (error == GIT_ENOTFOUND) ? 0 : error;
353
233
  }
354
234
 
355
- static void backend_free(git_config_backend *_backend)
235
+ static void config_file_free(git_config_backend *_backend)
356
236
  {
357
- diskfile_backend *backend = (diskfile_backend *)_backend;
237
+ config_file_backend *backend = GIT_CONTAINER_OF(_backend, config_file_backend, parent);
358
238
 
359
239
  if (backend == NULL)
360
240
  return;
361
241
 
362
242
  config_file_clear(&backend->file);
363
- diskfile_entries_free(backend->header.entries);
364
- git_mutex_free(&backend->header.values_mutex);
243
+ git_config_entries_free(backend->entries);
244
+ git_mutex_free(&backend->values_mutex);
365
245
  git__free(backend);
366
246
  }
367
247
 
368
- static void config_iterator_free(
369
- git_config_iterator* iter)
370
- {
371
- iter->backend->free(iter->backend);
372
- git__free(iter);
373
- }
374
-
375
- static int config_iterator_next(
376
- git_config_entry **entry,
377
- git_config_iterator *iter)
378
- {
379
- git_config_file_iter *it = (git_config_file_iter *) iter;
380
-
381
- if (!it->head)
382
- return GIT_ITEROVER;
383
-
384
- *entry = it->head->entry;
385
- it->head = it->head->next;
386
-
387
- return 0;
388
- }
389
-
390
- static int config_iterator_new(
248
+ static int config_file_iterator(
391
249
  git_config_iterator **iter,
392
- struct git_config_backend* backend)
250
+ struct git_config_backend *backend)
393
251
  {
394
- diskfile_header *h;
395
- git_config_file_iter *it;
396
- git_config_backend *snapshot;
397
- diskfile_header *bh = (diskfile_header *) backend;
252
+ config_file_backend *b = GIT_CONTAINER_OF(backend, config_file_backend, parent);
253
+ git_config_entries *dupped = NULL, *entries = NULL;
398
254
  int error;
399
255
 
400
- if ((error = config_snapshot(&snapshot, backend)) < 0)
401
- return error;
402
-
403
- if ((error = snapshot->open(snapshot, bh->level, bh->repo)) < 0)
404
- return error;
405
-
406
- it = git__calloc(1, sizeof(git_config_file_iter));
407
- GITERR_CHECK_ALLOC(it);
408
-
409
- h = (diskfile_header *)snapshot;
410
-
411
- it->parent.backend = snapshot;
412
- it->head = h->entries->list;
413
- it->parent.next = config_iterator_next;
414
- it->parent.free = config_iterator_free;
256
+ if ((error = config_file_refresh(backend)) < 0 ||
257
+ (error = config_file_entries_take(&entries, b)) < 0 ||
258
+ (error = git_config_entries_dup(&dupped, entries)) < 0 ||
259
+ (error = git_config_entries_iterator_new(iter, dupped)) < 0)
260
+ goto out;
415
261
 
416
- *iter = (git_config_iterator *) it;
262
+ out:
263
+ /* Let iterator delete duplicated entries when it's done */
264
+ git_config_entries_free(entries);
265
+ git_config_entries_free(dupped);
266
+ return error;
267
+ }
417
268
 
418
- return 0;
269
+ static int config_file_snapshot(git_config_backend **out, git_config_backend *backend)
270
+ {
271
+ return git_config_backend_snapshot(out, backend);
419
272
  }
420
273
 
421
- static int config_set(git_config_backend *cfg, const char *name, const char *value)
274
+ static int config_file_set(git_config_backend *cfg, const char *name, const char *value)
422
275
  {
423
- diskfile_backend *b = (diskfile_backend *)cfg;
424
- diskfile_entries *entries;
425
- git_strmap *entry_map;
276
+ config_file_backend *b = GIT_CONTAINER_OF(cfg, config_file_backend, parent);
277
+ git_config_entries *entries;
278
+ git_config_entry *existing;
426
279
  char *key, *esc_value = NULL;
427
- khiter_t pos;
428
- int rval, ret;
429
-
430
- if ((rval = git_config__normalize_name(name, &key)) < 0)
431
- return rval;
432
-
433
- if ((entries = diskfile_entries_take(&b->header)) == NULL)
434
- return -1;
435
- entry_map = entries->map;
280
+ int error;
436
281
 
437
- /*
438
- * Try to find it in the existing values and update it if it
439
- * only has one value.
440
- */
441
- pos = git_strmap_lookup_index(entry_map, key);
442
- if (git_strmap_valid_index(entry_map, pos)) {
443
- config_entry_list *existing = git_strmap_value_at(entry_map, pos);
282
+ if ((error = git_config__normalize_name(name, &key)) < 0)
283
+ return error;
444
284
 
445
- if (existing->next != NULL) {
446
- giterr_set(GITERR_CONFIG, "multivar incompatible with simple set");
447
- ret = -1;
448
- goto out;
449
- }
285
+ if ((error = config_file_entries_take(&entries, b)) < 0)
286
+ return error;
450
287
 
451
- if (existing->entry->include_depth) {
452
- giterr_set(GITERR_CONFIG, "modifying included variable is not supported");
453
- ret = -1;
288
+ /* Check whether we'd be modifying an included or multivar key */
289
+ if ((error = git_config_entries_get_unique(&existing, entries, key)) < 0) {
290
+ if (error != GIT_ENOTFOUND)
454
291
  goto out;
455
- }
456
-
292
+ error = 0;
293
+ } else if ((!existing->value && !value) ||
294
+ (existing->value && value && !strcmp(existing->value, value))) {
457
295
  /* don't update if old and new values already match */
458
- if ((!existing->entry->value && !value) ||
459
- (existing->entry->value && value &&
460
- !strcmp(existing->entry->value, value))) {
461
- ret = 0;
462
- goto out;
463
- }
296
+ error = 0;
297
+ goto out;
464
298
  }
465
299
 
466
300
  /* No early returns due to sanity checks, let's write it out and refresh */
467
-
468
301
  if (value) {
469
302
  esc_value = escape_value(value);
470
- GITERR_CHECK_ALLOC(esc_value);
303
+ GIT_ERROR_CHECK_ALLOC(esc_value);
471
304
  }
472
305
 
473
- if ((ret = config_write(b, name, key, NULL, esc_value)) < 0)
306
+ if ((error = config_file_write(b, name, key, NULL, esc_value)) < 0)
474
307
  goto out;
475
308
 
476
- ret = config_refresh(cfg);
477
-
478
309
  out:
479
- diskfile_entries_free(entries);
310
+ git_config_entries_free(entries);
480
311
  git__free(esc_value);
481
312
  git__free(key);
482
- return ret;
313
+ return error;
483
314
  }
484
315
 
485
316
  /* release the map containing the entry as an equivalent to freeing it */
486
- static void free_diskfile_entry(git_config_entry *entry)
317
+ static void config_file_entry_free(git_config_entry *entry)
487
318
  {
488
- diskfile_entries *map = (diskfile_entries *) entry->payload;
489
- diskfile_entries_free(map);
319
+ git_config_entries *entries = (git_config_entries *) entry->payload;
320
+ git_config_entries_free(entries);
490
321
  }
491
322
 
492
323
  /*
493
324
  * Internal function that actually gets the value in string form
494
325
  */
495
- static int config_get(git_config_backend *cfg, const char *key, git_config_entry **out)
326
+ static int config_file_get(git_config_backend *cfg, const char *key, git_config_entry **out)
496
327
  {
497
- diskfile_header *h = (diskfile_header *)cfg;
498
- diskfile_entries *entries;
499
- git_strmap *entry_map;
500
- khiter_t pos;
501
- config_entry_list *var;
328
+ config_file_backend *h = GIT_CONTAINER_OF(cfg, config_file_backend, parent);
329
+ git_config_entries *entries = NULL;
330
+ git_config_entry *entry;
502
331
  int error = 0;
503
332
 
504
- if (!h->parent.readonly && ((error = config_refresh(cfg)) < 0))
333
+ if (!h->parent.readonly && ((error = config_file_refresh(cfg)) < 0))
505
334
  return error;
506
335
 
507
- if ((entries = diskfile_entries_take(h)) == NULL)
508
- return -1;
509
- entry_map = entries->map;
510
-
511
- pos = git_strmap_lookup_index(entry_map, key);
336
+ if ((error = config_file_entries_take(&entries, h)) < 0)
337
+ return error;
512
338
 
513
- /* no error message; the config system will write one */
514
- if (!git_strmap_valid_index(entry_map, pos)) {
515
- diskfile_entries_free(entries);
516
- return GIT_ENOTFOUND;
339
+ if ((error = (git_config_entries_get(&entry, entries, key))) < 0) {
340
+ git_config_entries_free(entries);
341
+ return error;
517
342
  }
518
343
 
519
- var = git_strmap_value_at(entry_map, pos);
520
- while (var->next)
521
- var = var->next;
522
-
523
- *out = var->entry;
524
- (*out)->free = free_diskfile_entry;
525
- (*out)->payload = entries;
344
+ entry->free = config_file_entry_free;
345
+ entry->payload = entries;
346
+ *out = entry;
526
347
 
527
- return error;
348
+ return 0;
528
349
  }
529
350
 
530
- static int config_set_multivar(
351
+ static int config_file_set_multivar(
531
352
  git_config_backend *cfg, const char *name, const char *regexp, const char *value)
532
353
  {
533
- diskfile_backend *b = (diskfile_backend *)cfg;
534
- char *key;
535
- regex_t preg;
354
+ config_file_backend *b = GIT_CONTAINER_OF(cfg, config_file_backend, parent);
355
+ git_regexp preg;
536
356
  int result;
357
+ char *key;
537
358
 
538
359
  assert(regexp);
539
360
 
540
361
  if ((result = git_config__normalize_name(name, &key)) < 0)
541
362
  return result;
542
363
 
543
- result = p_regcomp(&preg, regexp, REG_EXTENDED);
544
- if (result != 0) {
545
- giterr_set_regex(&preg, result);
546
- result = -1;
364
+ if ((result = git_regexp_compile(&preg, regexp, 0)) < 0)
547
365
  goto out;
548
- }
549
366
 
550
- /* If we do have it, set call config_write() and reload */
551
- if ((result = config_write(b, name, key, &preg, value)) < 0)
367
+ /* If we do have it, set call config_file_write() and reload */
368
+ if ((result = config_file_write(b, name, key, &preg, value)) < 0)
552
369
  goto out;
553
370
 
554
- result = config_refresh(cfg);
555
-
556
371
  out:
557
372
  git__free(key);
558
- regfree(&preg);
373
+ git_regexp_dispose(&preg);
559
374
 
560
375
  return result;
561
376
  }
562
377
 
563
- static int config_delete(git_config_backend *cfg, const char *name)
378
+ static int config_file_delete(git_config_backend *cfg, const char *name)
564
379
  {
565
- config_entry_list *var;
566
- diskfile_backend *b = (diskfile_backend *)cfg;
567
- diskfile_entries *map;
568
- git_strmap *entry_map;
569
- char *key;
570
- int result;
571
- khiter_t pos;
572
-
573
- if ((result = git_config__normalize_name(name, &key)) < 0)
574
- return result;
575
-
576
- if ((map = diskfile_entries_take(&b->header)) == NULL)
577
- return -1;
578
- entry_map = b->header.entries->map;
579
-
580
- pos = git_strmap_lookup_index(entry_map, key);
581
- git__free(key);
582
-
583
- if (!git_strmap_valid_index(entry_map, pos)) {
584
- diskfile_entries_free(map);
585
- giterr_set(GITERR_CONFIG, "could not find key '%s' to delete", name);
586
- return GIT_ENOTFOUND;
587
- }
380
+ config_file_backend *b = GIT_CONTAINER_OF(cfg, config_file_backend, parent);
381
+ git_config_entries *entries = NULL;
382
+ git_config_entry *entry;
383
+ char *key = NULL;
384
+ int error;
588
385
 
589
- var = git_strmap_value_at(entry_map, pos);
590
- diskfile_entries_free(map);
386
+ if ((error = git_config__normalize_name(name, &key)) < 0)
387
+ goto out;
591
388
 
592
- if (var->entry->include_depth) {
593
- giterr_set(GITERR_CONFIG, "cannot delete included variable");
594
- return -1;
595
- }
389
+ if ((error = config_file_entries_take(&entries, b)) < 0)
390
+ goto out;
596
391
 
597
- if (var->next != NULL) {
598
- giterr_set(GITERR_CONFIG, "cannot delete multivar with a single delete");
599
- return -1;
392
+ /* Check whether we'd be modifying an included or multivar key */
393
+ if ((error = git_config_entries_get_unique(&entry, entries, key)) < 0) {
394
+ if (error == GIT_ENOTFOUND)
395
+ git_error_set(GIT_ERROR_CONFIG, "could not find key '%s' to delete", name);
396
+ goto out;
600
397
  }
601
398
 
602
- if ((result = config_write(b, name, var->entry->name, NULL, NULL)) < 0)
603
- return result;
399
+ if ((error = config_file_write(b, name, entry->name, NULL, NULL)) < 0)
400
+ goto out;
604
401
 
605
- return config_refresh(cfg);
402
+ out:
403
+ git_config_entries_free(entries);
404
+ git__free(key);
405
+ return error;
606
406
  }
607
407
 
608
- static int config_delete_multivar(git_config_backend *cfg, const char *name, const char *regexp)
408
+ static int config_file_delete_multivar(git_config_backend *cfg, const char *name, const char *regexp)
609
409
  {
610
- diskfile_backend *b = (diskfile_backend *)cfg;
611
- diskfile_entries *map;
612
- git_strmap *entry_map;
613
- char *key;
614
- regex_t preg;
410
+ config_file_backend *b = GIT_CONTAINER_OF(cfg, config_file_backend, parent);
411
+ git_config_entries *entries = NULL;
412
+ git_config_entry *entry = NULL;
413
+ git_regexp preg = GIT_REGEX_INIT;
414
+ char *key = NULL;
615
415
  int result;
616
- khiter_t pos;
617
416
 
618
417
  if ((result = git_config__normalize_name(name, &key)) < 0)
619
- return result;
620
-
621
- if ((map = diskfile_entries_take(&b->header)) == NULL)
622
- return -1;
623
- entry_map = b->header.entries->map;
624
-
625
- pos = git_strmap_lookup_index(entry_map, key);
626
-
627
- if (!git_strmap_valid_index(entry_map, pos)) {
628
- diskfile_entries_free(map);
629
- git__free(key);
630
- giterr_set(GITERR_CONFIG, "could not find key '%s' to delete", name);
631
- return GIT_ENOTFOUND;
632
- }
418
+ goto out;
633
419
 
634
- diskfile_entries_free(map);
420
+ if ((result = config_file_entries_take(&entries, b)) < 0)
421
+ goto out;
635
422
 
636
- result = p_regcomp(&preg, regexp, REG_EXTENDED);
637
- if (result != 0) {
638
- giterr_set_regex(&preg, result);
639
- result = -1;
423
+ if ((result = git_config_entries_get(&entry, entries, key)) < 0) {
424
+ if (result == GIT_ENOTFOUND)
425
+ git_error_set(GIT_ERROR_CONFIG, "could not find key '%s' to delete", name);
640
426
  goto out;
641
427
  }
642
428
 
643
- if ((result = config_write(b, name, key, &preg, NULL)) < 0)
429
+ if ((result = git_regexp_compile(&preg, regexp, 0)) < 0)
644
430
  goto out;
645
431
 
646
- result = config_refresh(cfg);
432
+ if ((result = config_file_write(b, name, key, &preg, NULL)) < 0)
433
+ goto out;
647
434
 
648
435
  out:
436
+ git_config_entries_free(entries);
649
437
  git__free(key);
650
- regfree(&preg);
438
+ git_regexp_dispose(&preg);
651
439
  return result;
652
440
  }
653
441
 
654
- static int config_snapshot(git_config_backend **out, git_config_backend *in)
442
+ static int config_file_lock(git_config_backend *_cfg)
655
443
  {
656
- diskfile_backend *b = (diskfile_backend *) in;
657
-
658
- return git_config_file__snapshot(out, b);
659
- }
660
-
661
- static int config_lock(git_config_backend *_cfg)
662
- {
663
- diskfile_backend *cfg = (diskfile_backend *) _cfg;
444
+ config_file_backend *cfg = GIT_CONTAINER_OF(_cfg, config_file_backend, parent);
664
445
  int error;
665
446
 
666
447
  if ((error = git_filebuf_open(&cfg->locked_buf, cfg->file.path, 0, GIT_CONFIG_FILE_MODE)) < 0)
@@ -677,9 +458,9 @@ static int config_lock(git_config_backend *_cfg)
677
458
 
678
459
  }
679
460
 
680
- static int config_unlock(git_config_backend *_cfg, int success)
461
+ static int config_file_unlock(git_config_backend *_cfg, int success)
681
462
  {
682
- diskfile_backend *cfg = (diskfile_backend *) _cfg;
463
+ config_file_backend *cfg = GIT_CONTAINER_OF(_cfg, config_file_backend, parent);
683
464
  int error = 0;
684
465
 
685
466
  if (success) {
@@ -694,147 +475,31 @@ static int config_unlock(git_config_backend *_cfg, int success)
694
475
  return error;
695
476
  }
696
477
 
697
- int git_config_file__ondisk(git_config_backend **out, const char *path)
478
+ int git_config_backend_from_file(git_config_backend **out, const char *path)
698
479
  {
699
- diskfile_backend *backend;
480
+ config_file_backend *backend;
700
481
 
701
- backend = git__calloc(1, sizeof(diskfile_backend));
702
- GITERR_CHECK_ALLOC(backend);
482
+ backend = git__calloc(1, sizeof(config_file_backend));
483
+ GIT_ERROR_CHECK_ALLOC(backend);
703
484
 
704
- backend->header.parent.version = GIT_CONFIG_BACKEND_VERSION;
705
- git_mutex_init(&backend->header.values_mutex);
485
+ backend->parent.version = GIT_CONFIG_BACKEND_VERSION;
486
+ git_mutex_init(&backend->values_mutex);
706
487
 
707
488
  backend->file.path = git__strdup(path);
708
- GITERR_CHECK_ALLOC(backend->file.path);
489
+ GIT_ERROR_CHECK_ALLOC(backend->file.path);
709
490
  git_array_init(backend->file.includes);
710
491
 
711
- backend->header.parent.open = config_open;
712
- backend->header.parent.get = config_get;
713
- backend->header.parent.set = config_set;
714
- backend->header.parent.set_multivar = config_set_multivar;
715
- backend->header.parent.del = config_delete;
716
- backend->header.parent.del_multivar = config_delete_multivar;
717
- backend->header.parent.iterator = config_iterator_new;
718
- backend->header.parent.snapshot = config_snapshot;
719
- backend->header.parent.lock = config_lock;
720
- backend->header.parent.unlock = config_unlock;
721
- backend->header.parent.free = backend_free;
722
-
723
- *out = (git_config_backend *)backend;
724
-
725
- return 0;
726
- }
727
-
728
- static int config_set_readonly(git_config_backend *cfg, const char *name, const char *value)
729
- {
730
- GIT_UNUSED(cfg);
731
- GIT_UNUSED(name);
732
- GIT_UNUSED(value);
733
-
734
- return config_error_readonly();
735
- }
736
-
737
- static int config_set_multivar_readonly(
738
- git_config_backend *cfg, const char *name, const char *regexp, const char *value)
739
- {
740
- GIT_UNUSED(cfg);
741
- GIT_UNUSED(name);
742
- GIT_UNUSED(regexp);
743
- GIT_UNUSED(value);
744
-
745
- return config_error_readonly();
746
- }
747
-
748
- static int config_delete_multivar_readonly(git_config_backend *cfg, const char *name, const char *regexp)
749
- {
750
- GIT_UNUSED(cfg);
751
- GIT_UNUSED(name);
752
- GIT_UNUSED(regexp);
753
-
754
- return config_error_readonly();
755
- }
756
-
757
- static int config_delete_readonly(git_config_backend *cfg, const char *name)
758
- {
759
- GIT_UNUSED(cfg);
760
- GIT_UNUSED(name);
761
-
762
- return config_error_readonly();
763
- }
764
-
765
- static int config_lock_readonly(git_config_backend *_cfg)
766
- {
767
- GIT_UNUSED(_cfg);
768
-
769
- return config_error_readonly();
770
- }
771
-
772
- static int config_unlock_readonly(git_config_backend *_cfg, int success)
773
- {
774
- GIT_UNUSED(_cfg);
775
- GIT_UNUSED(success);
776
-
777
- return config_error_readonly();
778
- }
779
-
780
- static void backend_readonly_free(git_config_backend *_backend)
781
- {
782
- diskfile_backend *backend = (diskfile_backend *)_backend;
783
-
784
- if (backend == NULL)
785
- return;
786
-
787
- diskfile_entries_free(backend->header.entries);
788
- git_mutex_free(&backend->header.values_mutex);
789
- git__free(backend);
790
- }
791
-
792
- static int config_readonly_open(git_config_backend *cfg, git_config_level_t level, const git_repository *repo)
793
- {
794
- diskfile_readonly_backend *b = (diskfile_readonly_backend *) cfg;
795
- diskfile_backend *src = b->snapshot_from;
796
- diskfile_header *src_header = &src->header;
797
- diskfile_entries *entries;
798
- int error;
799
-
800
- if (!src_header->parent.readonly && (error = config_refresh(&src_header->parent)) < 0)
801
- return error;
802
-
803
- /* We're just copying data, don't care about the level or repo*/
804
- GIT_UNUSED(level);
805
- GIT_UNUSED(repo);
806
-
807
- if ((entries = diskfile_entries_take(src_header)) == NULL)
808
- return -1;
809
- b->header.entries = entries;
810
-
811
- return 0;
812
- }
813
-
814
- int git_config_file__snapshot(git_config_backend **out, diskfile_backend *in)
815
- {
816
- diskfile_readonly_backend *backend;
817
-
818
- backend = git__calloc(1, sizeof(diskfile_readonly_backend));
819
- GITERR_CHECK_ALLOC(backend);
820
-
821
- backend->header.parent.version = GIT_CONFIG_BACKEND_VERSION;
822
- git_mutex_init(&backend->header.values_mutex);
823
-
824
- backend->snapshot_from = in;
825
-
826
- backend->header.parent.readonly = 1;
827
- backend->header.parent.version = GIT_CONFIG_BACKEND_VERSION;
828
- backend->header.parent.open = config_readonly_open;
829
- backend->header.parent.get = config_get;
830
- backend->header.parent.set = config_set_readonly;
831
- backend->header.parent.set_multivar = config_set_multivar_readonly;
832
- backend->header.parent.del = config_delete_readonly;
833
- backend->header.parent.del_multivar = config_delete_multivar_readonly;
834
- backend->header.parent.iterator = config_iterator_new;
835
- backend->header.parent.lock = config_lock_readonly;
836
- backend->header.parent.unlock = config_unlock_readonly;
837
- backend->header.parent.free = backend_readonly_free;
492
+ backend->parent.open = config_file_open;
493
+ backend->parent.get = config_file_get;
494
+ backend->parent.set = config_file_set;
495
+ backend->parent.set_multivar = config_file_set_multivar;
496
+ backend->parent.del = config_file_delete;
497
+ backend->parent.del_multivar = config_file_delete_multivar;
498
+ backend->parent.iterator = config_file_iterator;
499
+ backend->parent.snapshot = config_file_snapshot;
500
+ backend->parent.lock = config_file_lock;
501
+ backend->parent.unlock = config_file_unlock;
502
+ backend->parent.free = config_file_free;
838
503
 
839
504
  *out = (git_config_backend *)backend;
840
505
 
@@ -882,15 +547,17 @@ static char *escape_value(const char *ptr)
882
547
  return git_buf_detach(&buf);
883
548
  }
884
549
 
885
- static int parse_include(git_config_parser *reader,
886
- diskfile_parse_state *parse_data, const char *file)
550
+ static int parse_include(config_file_parse_data *parse_data, const char *file)
887
551
  {
888
- struct config_file *include;
552
+ config_file *include;
889
553
  git_buf path = GIT_BUF_INIT;
890
554
  char *dir;
891
555
  int result;
892
556
 
893
- if ((result = git_path_dirname_r(&path, reader->file->path)) < 0)
557
+ if (!file)
558
+ return 0;
559
+
560
+ if ((result = git_path_dirname_r(&path, parse_data->file->path)) < 0)
894
561
  return result;
895
562
 
896
563
  dir = git_buf_detach(&path);
@@ -900,16 +567,17 @@ static int parse_include(git_config_parser *reader,
900
567
  if (result < 0)
901
568
  return result;
902
569
 
903
- include = git_array_alloc(reader->file->includes);
570
+ include = git_array_alloc(parse_data->file->includes);
571
+ GIT_ERROR_CHECK_ALLOC(include);
904
572
  memset(include, 0, sizeof(*include));
905
573
  git_array_init(include->includes);
906
574
  include->path = git_buf_detach(&path);
907
575
 
908
- result = config_read(parse_data->entries, parse_data->repo,
909
- include, parse_data->level, parse_data->depth+1);
576
+ result = config_file_read(parse_data->entries, parse_data->repo, include,
577
+ parse_data->level, parse_data->depth+1);
910
578
 
911
579
  if (result == GIT_ENOTFOUND) {
912
- giterr_clear();
580
+ git_error_clear();
913
581
  result = 0;
914
582
  }
915
583
 
@@ -920,41 +588,41 @@ static int do_match_gitdir(
920
588
  int *matches,
921
589
  const git_repository *repo,
922
590
  const char *cfg_file,
923
- const char *value,
591
+ const char *condition,
924
592
  bool case_insensitive)
925
593
  {
926
- git_buf path = GIT_BUF_INIT;
927
- int error, fnmatch_flags;
928
-
929
- if (value[0] == '.' && git_path_is_dirsep(value[1])) {
930
- git_path_dirname_r(&path, cfg_file);
931
- git_buf_joinpath(&path, path.ptr, value + 2);
932
- } else if (value[0] == '~' && git_path_is_dirsep(value[1]))
933
- git_sysdir_expand_global_file(&path, value + 1);
934
- else if (!git_path_is_absolute(value))
935
- git_buf_joinpath(&path, "**", value);
594
+ git_buf pattern = GIT_BUF_INIT, gitdir = GIT_BUF_INIT;
595
+ int error;
596
+
597
+ if (condition[0] == '.' && git_path_is_dirsep(condition[1])) {
598
+ git_path_dirname_r(&pattern, cfg_file);
599
+ git_buf_joinpath(&pattern, pattern.ptr, condition + 2);
600
+ } else if (condition[0] == '~' && git_path_is_dirsep(condition[1]))
601
+ git_sysdir_expand_global_file(&pattern, condition + 1);
602
+ else if (!git_path_is_absolute(condition))
603
+ git_buf_joinpath(&pattern, "**", condition);
936
604
  else
937
- git_buf_sets(&path, value);
605
+ git_buf_sets(&pattern, condition);
938
606
 
939
- if (git_buf_oom(&path)) {
607
+ if (git_path_is_dirsep(condition[strlen(condition) - 1]))
608
+ git_buf_puts(&pattern, "**");
609
+
610
+ if (git_buf_oom(&pattern)) {
940
611
  error = -1;
941
612
  goto out;
942
613
  }
943
614
 
944
- if (git_path_is_dirsep(value[strlen(value) - 1]))
945
- git_buf_puts(&path, "**");
946
-
947
- fnmatch_flags = FNM_PATHNAME|FNM_LEADING_DIR;
948
- if (case_insensitive)
949
- fnmatch_flags |= FNM_IGNORECASE;
950
-
951
- if ((error = p_fnmatch(path.ptr, git_repository_path(repo), fnmatch_flags)) < 0)
615
+ if ((error = git_repository_item_path(&gitdir, repo, GIT_REPOSITORY_ITEM_GITDIR)) < 0)
952
616
  goto out;
953
617
 
954
- *matches = (error == 0);
618
+ if (git_path_is_dirsep(gitdir.ptr[gitdir.size - 1]))
619
+ git_buf_truncate(&gitdir, gitdir.size - 1);
955
620
 
621
+ *matches = wildmatch(pattern.ptr, gitdir.ptr,
622
+ WM_PATHNAME | (case_insensitive ? WM_CASEFOLD : 0)) == WM_MATCH;
956
623
  out:
957
- git_buf_dispose(&path);
624
+ git_buf_dispose(&pattern);
625
+ git_buf_dispose(&gitdir);
958
626
  return error;
959
627
  }
960
628
 
@@ -976,22 +644,73 @@ static int conditional_match_gitdir_i(
976
644
  return do_match_gitdir(matches, repo, cfg_file, value, true);
977
645
  }
978
646
 
647
+ static int conditional_match_onbranch(
648
+ int *matches,
649
+ const git_repository *repo,
650
+ const char *cfg_file,
651
+ const char *condition)
652
+ {
653
+ git_buf reference = GIT_BUF_INIT, buf = GIT_BUF_INIT;
654
+ int error;
655
+
656
+ GIT_UNUSED(cfg_file);
657
+
658
+ /*
659
+ * NOTE: you cannot use `git_repository_head` here. Looking up the
660
+ * HEAD reference will create the ODB, which causes us to read the
661
+ * repo's config for keys like core.precomposeUnicode. As we're
662
+ * just parsing the config right now, though, this would result in
663
+ * an endless recursion.
664
+ */
665
+
666
+ if ((error = git_buf_joinpath(&buf, git_repository_path(repo), GIT_HEAD_FILE)) < 0 ||
667
+ (error = git_futils_readbuffer(&reference, buf.ptr)) < 0)
668
+ goto out;
669
+ git_buf_rtrim(&reference);
670
+
671
+ if (git__strncmp(reference.ptr, GIT_SYMREF, strlen(GIT_SYMREF)))
672
+ goto out;
673
+ git_buf_consume(&reference, reference.ptr + strlen(GIT_SYMREF));
674
+
675
+ if (git__strncmp(reference.ptr, GIT_REFS_HEADS_DIR, strlen(GIT_REFS_HEADS_DIR)))
676
+ goto out;
677
+ git_buf_consume(&reference, reference.ptr + strlen(GIT_REFS_HEADS_DIR));
678
+
679
+ /*
680
+ * If the condition ends with a '/', then we should treat it as if
681
+ * it had '**' appended.
682
+ */
683
+ if ((error = git_buf_sets(&buf, condition)) < 0)
684
+ goto out;
685
+ if (git_path_is_dirsep(condition[strlen(condition) - 1]) &&
686
+ (error = git_buf_puts(&buf, "**")) < 0)
687
+ goto out;
688
+
689
+ *matches = wildmatch(buf.ptr, reference.ptr, WM_PATHNAME) == WM_MATCH;
690
+ out:
691
+ git_buf_dispose(&reference);
692
+ git_buf_dispose(&buf);
693
+
694
+ return error;
695
+
696
+ }
697
+
979
698
  static const struct {
980
699
  const char *prefix;
981
700
  int (*matches)(int *matches, const git_repository *repo, const char *cfg, const char *value);
982
701
  } conditions[] = {
983
702
  { "gitdir:", conditional_match_gitdir },
984
- { "gitdir/i:", conditional_match_gitdir_i }
703
+ { "gitdir/i:", conditional_match_gitdir_i },
704
+ { "onbranch:", conditional_match_onbranch }
985
705
  };
986
706
 
987
- static int parse_conditional_include(git_config_parser *reader,
988
- diskfile_parse_state *parse_data, const char *section, const char *file)
707
+ static int parse_conditional_include(config_file_parse_data *parse_data, const char *section, const char *file)
989
708
  {
990
709
  char *condition;
991
710
  size_t i;
992
711
  int error = 0, matches;
993
712
 
994
- if (!parse_data->repo)
713
+ if (!parse_data->repo || !file)
995
714
  return 0;
996
715
 
997
716
  condition = git__substrdup(section + strlen("includeIf."),
@@ -1003,12 +722,12 @@ static int parse_conditional_include(git_config_parser *reader,
1003
722
 
1004
723
  if ((error = conditions[i].matches(&matches,
1005
724
  parse_data->repo,
1006
- parse_data->file_path,
725
+ parse_data->file->path,
1007
726
  condition + strlen(conditions[i].prefix))) < 0)
1008
727
  break;
1009
728
 
1010
729
  if (matches)
1011
- error = parse_include(reader, parse_data, file);
730
+ error = parse_include(parse_data, file);
1012
731
 
1013
732
  break;
1014
733
  }
@@ -1026,17 +745,25 @@ static int read_on_variable(
1026
745
  size_t line_len,
1027
746
  void *data)
1028
747
  {
1029
- diskfile_parse_state *parse_data = (diskfile_parse_state *)data;
748
+ config_file_parse_data *parse_data = (config_file_parse_data *)data;
1030
749
  git_buf buf = GIT_BUF_INIT;
1031
750
  git_config_entry *entry;
1032
751
  const char *c;
1033
752
  int result = 0;
1034
753
 
754
+ GIT_UNUSED(reader);
1035
755
  GIT_UNUSED(line);
1036
756
  GIT_UNUSED(line_len);
1037
757
 
1038
- git_buf_puts(&buf, current_section);
1039
- git_buf_putc(&buf, '.');
758
+ if (current_section) {
759
+ /* TODO: Once warnings lang, we should likely warn
760
+ * here. Git appears to warn in most cases if it sees
761
+ * un-namespaced config options.
762
+ */
763
+ git_buf_puts(&buf, current_section);
764
+ git_buf_putc(&buf, '.');
765
+ }
766
+
1040
767
  for (c = var_name; *c; c++)
1041
768
  git_buf_putc(&buf, git__tolower(*c));
1042
769
 
@@ -1044,69 +771,94 @@ static int read_on_variable(
1044
771
  return -1;
1045
772
 
1046
773
  entry = git__calloc(1, sizeof(git_config_entry));
1047
- GITERR_CHECK_ALLOC(entry);
774
+ GIT_ERROR_CHECK_ALLOC(entry);
1048
775
  entry->name = git_buf_detach(&buf);
1049
776
  entry->value = var_value ? git__strdup(var_value) : NULL;
1050
777
  entry->level = parse_data->level;
1051
778
  entry->include_depth = parse_data->depth;
1052
779
 
1053
- if ((result = diskfile_entries_append(parse_data->entries, entry)) < 0)
780
+ if ((result = git_config_entries_append(parse_data->entries, entry)) < 0)
1054
781
  return result;
1055
782
 
1056
783
  result = 0;
1057
784
 
1058
785
  /* Add or append the new config option */
1059
786
  if (!git__strcmp(entry->name, "include.path"))
1060
- result = parse_include(reader, parse_data, entry->value);
787
+ result = parse_include(parse_data, entry->value);
1061
788
  else if (!git__prefixcmp(entry->name, "includeif.") &&
1062
789
  !git__suffixcmp(entry->name, ".path"))
1063
- result = parse_conditional_include(reader, parse_data,
1064
- entry->name, entry->value);
790
+ result = parse_conditional_include(parse_data, entry->name, entry->value);
1065
791
 
1066
792
  return result;
1067
793
  }
1068
794
 
1069
- static int config_read(
1070
- diskfile_entries *entries,
795
+ static int config_file_read_buffer(
796
+ git_config_entries *entries,
1071
797
  const git_repository *repo,
1072
- git_config_file *file,
798
+ config_file *file,
1073
799
  git_config_level_t level,
1074
- int depth)
800
+ int depth,
801
+ const char *buf,
802
+ size_t buflen)
1075
803
  {
1076
- diskfile_parse_state parse_data;
804
+ config_file_parse_data parse_data;
1077
805
  git_config_parser reader;
1078
- git_buf contents = GIT_BUF_INIT;
1079
806
  int error;
1080
807
 
1081
808
  if (depth >= MAX_INCLUDE_DEPTH) {
1082
- giterr_set(GITERR_CONFIG, "maximum config include depth reached");
809
+ git_error_set(GIT_ERROR_CONFIG, "maximum config include depth reached");
1083
810
  return -1;
1084
811
  }
1085
812
 
1086
- if ((error = git_futils_readbuffer(&contents, file->path)) < 0)
1087
- goto out;
1088
-
1089
- git_parse_ctx_init(&reader.ctx, contents.ptr, contents.size);
1090
-
1091
- if ((error = git_hash_buf(&file->checksum, contents.ptr, contents.size)) < 0)
1092
- goto out;
1093
-
1094
813
  /* Initialize the reading position */
1095
- reader.file = file;
1096
- git_parse_ctx_init(&reader.ctx, contents.ptr, contents.size);
814
+ reader.path = file->path;
815
+ git_parse_ctx_init(&reader.ctx, buf, buflen);
1097
816
 
1098
817
  /* If the file is empty, there's nothing for us to do */
1099
- if (!reader.ctx.content || *reader.ctx.content == '\0')
818
+ if (!reader.ctx.content || *reader.ctx.content == '\0') {
819
+ error = 0;
1100
820
  goto out;
821
+ }
1101
822
 
1102
823
  parse_data.repo = repo;
1103
- parse_data.file_path = file->path;
824
+ parse_data.file = file;
1104
825
  parse_data.entries = entries;
1105
826
  parse_data.level = level;
1106
827
  parse_data.depth = depth;
1107
828
 
1108
829
  error = git_config_parse(&reader, NULL, read_on_variable, NULL, NULL, &parse_data);
1109
830
 
831
+ out:
832
+ return error;
833
+ }
834
+
835
+ static int config_file_read(
836
+ git_config_entries *entries,
837
+ const git_repository *repo,
838
+ config_file *file,
839
+ git_config_level_t level,
840
+ int depth)
841
+ {
842
+ git_buf contents = GIT_BUF_INIT;
843
+ struct stat st;
844
+ int error;
845
+
846
+ if (p_stat(file->path, &st) < 0) {
847
+ error = git_path_set_error(errno, file->path, "stat");
848
+ goto out;
849
+ }
850
+
851
+ if ((error = git_futils_readbuffer(&contents, file->path)) < 0)
852
+ goto out;
853
+
854
+ git_futils_filestamp_set_from_stat(&file->stamp, &st);
855
+ if ((error = git_hash_buf(&file->checksum, contents.ptr, contents.size)) < 0)
856
+ goto out;
857
+
858
+ if ((error = config_file_read_buffer(entries, repo, file, level, depth,
859
+ contents.ptr, contents.size)) < 0)
860
+ goto out;
861
+
1110
862
  out:
1111
863
  git_buf_dispose(&contents);
1112
864
  return error;
@@ -1127,7 +879,7 @@ static int write_section(git_buf *fbuf, const char *key)
1127
879
  char *escaped;
1128
880
  git_buf_put(&buf, key, dot - key);
1129
881
  escaped = escape_value(dot + 1);
1130
- GITERR_CHECK_ALLOC(escaped);
882
+ GIT_ERROR_CHECK_ALLOC(escaped);
1131
883
  git_buf_printf(&buf, " \"%s\"", escaped);
1132
884
  git__free(escaped);
1133
885
  }
@@ -1169,7 +921,7 @@ struct write_data {
1169
921
  const char *section;
1170
922
  const char *orig_name;
1171
923
  const char *name;
1172
- const regex_t *preg;
924
+ const git_regexp *preg;
1173
925
  const char *value;
1174
926
  };
1175
927
 
@@ -1274,7 +1026,7 @@ static int write_on_variable(
1274
1026
 
1275
1027
  /* If we have a regex to match the value, see if it matches */
1276
1028
  if (has_matched && write_data->preg != NULL)
1277
- has_matched = (regexec(write_data->preg, var_value, 0, NULL, 0) == 0);
1029
+ has_matched = (git_regexp_match(write_data->preg, var_value) == 0);
1278
1030
 
1279
1031
  /* If this isn't the name/value we're looking for, simply dump the
1280
1032
  * existing data back out and continue on.
@@ -1335,75 +1087,55 @@ static int write_on_eof(
1335
1087
  /*
1336
1088
  * This is pretty much the parsing, except we write out anything we don't have
1337
1089
  */
1338
- static int config_write(diskfile_backend *cfg, const char *orig_key, const char *key, const regex_t *preg, const char* value)
1090
+ static int config_file_write(config_file_backend *cfg, const char *orig_key, const char *key, const git_regexp *preg, const char* value)
1091
+
1339
1092
  {
1340
- int result;
1341
- char *orig_section, *section, *orig_name, *name, *ldot;
1342
- git_filebuf file = GIT_FILEBUF_INIT;
1093
+ char *orig_section = NULL, *section = NULL, *orig_name, *name, *ldot;
1343
1094
  git_buf buf = GIT_BUF_INIT, contents = GIT_BUF_INIT;
1344
- git_config_parser reader;
1095
+ git_config_parser parser = GIT_CONFIG_PARSER_INIT;
1096
+ git_filebuf file = GIT_FILEBUF_INIT;
1345
1097
  struct write_data write_data;
1098
+ int error;
1346
1099
 
1347
- memset(&reader, 0, sizeof(reader));
1348
- reader.file = &cfg->file;
1100
+ memset(&write_data, 0, sizeof(write_data));
1349
1101
 
1350
1102
  if (cfg->locked) {
1351
- result = git_buf_puts(&contents, git_buf_cstr(&cfg->locked_content));
1103
+ error = git_buf_puts(&contents, git_buf_cstr(&cfg->locked_content) == NULL ? "" : git_buf_cstr(&cfg->locked_content));
1352
1104
  } else {
1353
- /* Lock the file */
1354
- if ((result = git_filebuf_open(
1355
- &file, cfg->file.path, GIT_FILEBUF_HASH_CONTENTS, GIT_CONFIG_FILE_MODE)) < 0) {
1356
- git_buf_dispose(&contents);
1357
- return result;
1358
- }
1105
+ if ((error = git_filebuf_open(&file, cfg->file.path, GIT_FILEBUF_HASH_CONTENTS,
1106
+ GIT_CONFIG_FILE_MODE)) < 0)
1107
+ goto done;
1359
1108
 
1360
1109
  /* We need to read in our own config file */
1361
- result = git_futils_readbuffer(&contents, cfg->file.path);
1110
+ error = git_futils_readbuffer(&contents, cfg->file.path);
1362
1111
  }
1112
+ if (error < 0 && error != GIT_ENOTFOUND)
1113
+ goto done;
1363
1114
 
1364
- /* Initialise the reading position */
1365
- if (result == 0 || result == GIT_ENOTFOUND) {
1366
- git_parse_ctx_init(&reader.ctx, contents.ptr, contents.size);
1367
- } else {
1368
- git_filebuf_cleanup(&file);
1369
- return -1; /* OS error when reading the file */
1370
- }
1115
+ if ((git_config_parser_init(&parser, cfg->file.path, contents.ptr, contents.size)) < 0)
1116
+ goto done;
1371
1117
 
1372
1118
  ldot = strrchr(key, '.');
1373
1119
  name = ldot + 1;
1374
1120
  section = git__strndup(key, ldot - key);
1375
- GITERR_CHECK_ALLOC(section);
1121
+ GIT_ERROR_CHECK_ALLOC(section);
1376
1122
 
1377
1123
  ldot = strrchr(orig_key, '.');
1378
1124
  orig_name = ldot + 1;
1379
1125
  orig_section = git__strndup(orig_key, ldot - orig_key);
1380
- GITERR_CHECK_ALLOC(orig_section);
1126
+ GIT_ERROR_CHECK_ALLOC(orig_section);
1381
1127
 
1382
1128
  write_data.buf = &buf;
1383
- git_buf_init(&write_data.buffered_comment, 0);
1384
1129
  write_data.orig_section = orig_section;
1385
1130
  write_data.section = section;
1386
- write_data.in_section = 0;
1387
- write_data.preg_replaced = 0;
1388
1131
  write_data.orig_name = orig_name;
1389
1132
  write_data.name = name;
1390
1133
  write_data.preg = preg;
1391
1134
  write_data.value = value;
1392
1135
 
1393
- result = git_config_parse(&reader,
1394
- write_on_section,
1395
- write_on_variable,
1396
- write_on_comment,
1397
- write_on_eof,
1398
- &write_data);
1399
- git__free(section);
1400
- git__free(orig_section);
1401
- git_buf_dispose(&write_data.buffered_comment);
1402
-
1403
- if (result < 0) {
1404
- git_filebuf_cleanup(&file);
1136
+ if ((error = git_config_parse(&parser, write_on_section, write_on_variable,
1137
+ write_on_comment, write_on_eof, &write_data)) < 0)
1405
1138
  goto done;
1406
- }
1407
1139
 
1408
1140
  if (cfg->locked) {
1409
1141
  size_t len = buf.asize;
@@ -1412,12 +1144,22 @@ static int config_write(diskfile_backend *cfg, const char *orig_key, const char
1412
1144
  git_buf_attach(&cfg->locked_content, git_buf_detach(&buf), len);
1413
1145
  } else {
1414
1146
  git_filebuf_write(&file, git_buf_cstr(&buf), git_buf_len(&buf));
1415
- result = git_filebuf_commit(&file);
1147
+
1148
+ if ((error = git_filebuf_commit(&file)) < 0)
1149
+ goto done;
1150
+
1151
+ if ((error = config_file_refresh_from_buffer(&cfg->parent, buf.ptr, buf.size)) < 0)
1152
+ goto done;
1416
1153
  }
1417
1154
 
1418
1155
  done:
1156
+ git__free(section);
1157
+ git__free(orig_section);
1158
+ git_buf_dispose(&write_data.buffered_comment);
1419
1159
  git_buf_dispose(&buf);
1420
1160
  git_buf_dispose(&contents);
1421
- git_parse_ctx_clear(&reader.ctx);
1422
- return result;
1161
+ git_filebuf_cleanup(&file);
1162
+ git_config_parser_dispose(&parser);
1163
+
1164
+ return error;
1423
1165
  }