rugged 0.28.5 → 0.99.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (379) hide show
  1. checksums.yaml +4 -4
  2. data/ext/rugged/extconf.rb +3 -1
  3. data/ext/rugged/rugged.c +35 -31
  4. data/ext/rugged/rugged.h +13 -0
  5. data/ext/rugged/rugged_blob.c +11 -9
  6. data/ext/rugged/rugged_commit.c +17 -15
  7. data/ext/rugged/rugged_diff.c +4 -26
  8. data/ext/rugged/rugged_index.c +4 -2
  9. data/ext/rugged/rugged_note.c +5 -3
  10. data/ext/rugged/rugged_object.c +57 -10
  11. data/ext/rugged/rugged_rebase.c +3 -1
  12. data/ext/rugged/rugged_remote.c +0 -6
  13. data/ext/rugged/rugged_repo.c +222 -17
  14. data/ext/rugged/rugged_tag.c +8 -6
  15. data/ext/rugged/rugged_tree.c +18 -16
  16. data/lib/rugged/version.rb +1 -1
  17. data/vendor/libgit2/CMakeLists.txt +38 -19
  18. data/vendor/libgit2/COPYING +28 -0
  19. data/vendor/libgit2/cmake/Modules/EnableWarnings.cmake +5 -1
  20. data/vendor/libgit2/cmake/Modules/FindCoreFoundation.cmake +2 -2
  21. data/vendor/libgit2/cmake/Modules/FindGSSAPI.cmake +1 -1
  22. data/vendor/libgit2/cmake/Modules/FindGSSFramework.cmake +28 -0
  23. data/vendor/libgit2/cmake/Modules/FindPCRE.cmake +38 -0
  24. data/vendor/libgit2/cmake/Modules/FindPCRE2.cmake +37 -0
  25. data/vendor/libgit2/cmake/Modules/FindSecurity.cmake +2 -2
  26. data/vendor/libgit2/cmake/Modules/FindStatNsec.cmake +6 -0
  27. data/vendor/libgit2/cmake/Modules/PkgBuildConfig.cmake +110 -0
  28. data/vendor/libgit2/cmake/Modules/SelectGSSAPI.cmake +53 -0
  29. data/vendor/libgit2/cmake/Modules/SelectHTTPSBackend.cmake +124 -0
  30. data/vendor/libgit2/cmake/Modules/SelectHashes.cmake +66 -0
  31. data/vendor/libgit2/deps/http-parser/http_parser.c +11 -6
  32. data/vendor/libgit2/deps/ntlmclient/CMakeLists.txt +21 -0
  33. data/vendor/libgit2/deps/ntlmclient/compat.h +33 -0
  34. data/vendor/libgit2/deps/ntlmclient/crypt.h +64 -0
  35. data/vendor/libgit2/deps/ntlmclient/crypt_commoncrypto.c +120 -0
  36. data/vendor/libgit2/deps/ntlmclient/crypt_commoncrypto.h +18 -0
  37. data/vendor/libgit2/deps/ntlmclient/crypt_mbedtls.c +145 -0
  38. data/vendor/libgit2/deps/ntlmclient/crypt_mbedtls.h +18 -0
  39. data/vendor/libgit2/deps/ntlmclient/crypt_openssl.c +130 -0
  40. data/vendor/libgit2/deps/ntlmclient/crypt_openssl.h +21 -0
  41. data/vendor/libgit2/deps/ntlmclient/ntlm.c +1422 -0
  42. data/vendor/libgit2/deps/ntlmclient/ntlm.h +174 -0
  43. data/vendor/libgit2/deps/ntlmclient/ntlmclient.h +320 -0
  44. data/vendor/libgit2/deps/ntlmclient/unicode.h +36 -0
  45. data/vendor/libgit2/deps/ntlmclient/unicode_builtin.c +445 -0
  46. data/vendor/libgit2/deps/ntlmclient/unicode_iconv.c +201 -0
  47. data/vendor/libgit2/deps/ntlmclient/utf8.h +1257 -0
  48. data/vendor/libgit2/deps/ntlmclient/util.c +21 -0
  49. data/vendor/libgit2/deps/ntlmclient/util.h +14 -0
  50. data/vendor/libgit2/deps/pcre/CMakeLists.txt +140 -0
  51. data/vendor/libgit2/deps/pcre/COPYING +5 -0
  52. data/vendor/libgit2/deps/pcre/cmake/COPYING-CMAKE-SCRIPTS +22 -0
  53. data/vendor/libgit2/deps/pcre/cmake/FindEditline.cmake +17 -0
  54. data/vendor/libgit2/deps/pcre/cmake/FindPackageHandleStandardArgs.cmake +58 -0
  55. data/vendor/libgit2/deps/pcre/cmake/FindReadline.cmake +29 -0
  56. data/vendor/libgit2/deps/pcre/config.h.in +57 -0
  57. data/vendor/libgit2/deps/pcre/pcre.h +641 -0
  58. data/vendor/libgit2/deps/pcre/pcre_byte_order.c +319 -0
  59. data/vendor/libgit2/deps/pcre/pcre_chartables.c +198 -0
  60. data/vendor/libgit2/deps/pcre/pcre_compile.c +9800 -0
  61. data/vendor/libgit2/deps/pcre/pcre_config.c +190 -0
  62. data/vendor/libgit2/deps/pcre/pcre_dfa_exec.c +3676 -0
  63. data/vendor/libgit2/deps/pcre/pcre_exec.c +7173 -0
  64. data/vendor/libgit2/deps/pcre/pcre_fullinfo.c +245 -0
  65. data/vendor/libgit2/deps/pcre/pcre_get.c +669 -0
  66. data/vendor/libgit2/deps/pcre/pcre_globals.c +86 -0
  67. data/vendor/libgit2/deps/pcre/pcre_internal.h +2787 -0
  68. data/vendor/libgit2/deps/pcre/pcre_jit_compile.c +11913 -0
  69. data/vendor/libgit2/deps/pcre/pcre_maketables.c +156 -0
  70. data/vendor/libgit2/deps/pcre/pcre_newline.c +210 -0
  71. data/vendor/libgit2/deps/pcre/pcre_ord2utf8.c +94 -0
  72. data/vendor/libgit2/deps/pcre/pcre_printint.c +834 -0
  73. data/vendor/libgit2/deps/pcre/pcre_refcount.c +92 -0
  74. data/vendor/libgit2/deps/pcre/pcre_string_utils.c +211 -0
  75. data/vendor/libgit2/deps/pcre/pcre_study.c +1686 -0
  76. data/vendor/libgit2/deps/pcre/pcre_tables.c +727 -0
  77. data/vendor/libgit2/deps/pcre/pcre_ucd.c +3644 -0
  78. data/vendor/libgit2/deps/pcre/pcre_valid_utf8.c +301 -0
  79. data/vendor/libgit2/deps/pcre/pcre_version.c +98 -0
  80. data/vendor/libgit2/deps/pcre/pcre_xclass.c +268 -0
  81. data/vendor/libgit2/deps/pcre/pcreposix.c +421 -0
  82. data/vendor/libgit2/deps/pcre/pcreposix.h +117 -0
  83. data/vendor/libgit2/deps/pcre/ucp.h +224 -0
  84. data/vendor/libgit2/deps/zlib/adler32.c +0 -7
  85. data/vendor/libgit2/deps/zlib/crc32.c +0 -7
  86. data/vendor/libgit2/include/git2.h +2 -0
  87. data/vendor/libgit2/include/git2/apply.h +22 -2
  88. data/vendor/libgit2/include/git2/attr.h +23 -13
  89. data/vendor/libgit2/include/git2/blame.h +2 -2
  90. data/vendor/libgit2/include/git2/blob.h +44 -12
  91. data/vendor/libgit2/include/git2/branch.h +74 -57
  92. data/vendor/libgit2/include/git2/buffer.h +20 -14
  93. data/vendor/libgit2/include/git2/cert.h +135 -0
  94. data/vendor/libgit2/include/git2/checkout.h +46 -14
  95. data/vendor/libgit2/include/git2/cherrypick.h +3 -3
  96. data/vendor/libgit2/include/git2/clone.h +2 -2
  97. data/vendor/libgit2/include/git2/commit.h +23 -1
  98. data/vendor/libgit2/include/git2/common.h +15 -6
  99. data/vendor/libgit2/include/git2/config.h +12 -12
  100. data/vendor/libgit2/include/git2/cred_helpers.h +4 -42
  101. data/vendor/libgit2/include/git2/credential.h +314 -0
  102. data/vendor/libgit2/include/git2/credential_helpers.h +52 -0
  103. data/vendor/libgit2/include/git2/deprecated.h +314 -3
  104. data/vendor/libgit2/include/git2/describe.h +4 -4
  105. data/vendor/libgit2/include/git2/diff.h +16 -14
  106. data/vendor/libgit2/include/git2/errors.h +4 -2
  107. data/vendor/libgit2/include/git2/filter.h +8 -0
  108. data/vendor/libgit2/include/git2/index.h +2 -1
  109. data/vendor/libgit2/include/git2/indexer.h +48 -4
  110. data/vendor/libgit2/include/git2/merge.h +6 -10
  111. data/vendor/libgit2/include/git2/net.h +0 -5
  112. data/vendor/libgit2/include/git2/object.h +2 -14
  113. data/vendor/libgit2/include/git2/odb.h +3 -2
  114. data/vendor/libgit2/include/git2/odb_backend.h +5 -4
  115. data/vendor/libgit2/include/git2/oid.h +11 -6
  116. data/vendor/libgit2/include/git2/pack.h +12 -1
  117. data/vendor/libgit2/include/git2/proxy.h +6 -4
  118. data/vendor/libgit2/include/git2/rebase.h +46 -2
  119. data/vendor/libgit2/include/git2/refs.h +19 -0
  120. data/vendor/libgit2/include/git2/remote.h +40 -15
  121. data/vendor/libgit2/include/git2/repository.h +24 -2
  122. data/vendor/libgit2/include/git2/revert.h +1 -1
  123. data/vendor/libgit2/include/git2/revwalk.h +7 -3
  124. data/vendor/libgit2/include/git2/stash.h +4 -4
  125. data/vendor/libgit2/include/git2/status.h +25 -16
  126. data/vendor/libgit2/include/git2/submodule.h +20 -3
  127. data/vendor/libgit2/include/git2/sys/alloc.h +9 -9
  128. data/vendor/libgit2/include/git2/sys/cred.h +15 -0
  129. data/vendor/libgit2/include/git2/sys/credential.h +90 -0
  130. data/vendor/libgit2/include/git2/sys/index.h +4 -2
  131. data/vendor/libgit2/include/git2/sys/mempack.h +2 -1
  132. data/vendor/libgit2/include/git2/sys/merge.h +1 -1
  133. data/vendor/libgit2/include/git2/sys/odb_backend.h +48 -4
  134. data/vendor/libgit2/include/git2/sys/refdb_backend.h +57 -21
  135. data/vendor/libgit2/include/git2/sys/repository.h +17 -6
  136. data/vendor/libgit2/include/git2/sys/transport.h +4 -4
  137. data/vendor/libgit2/include/git2/tag.h +11 -2
  138. data/vendor/libgit2/include/git2/trace.h +2 -2
  139. data/vendor/libgit2/include/git2/transport.h +11 -340
  140. data/vendor/libgit2/include/git2/tree.h +5 -3
  141. data/vendor/libgit2/include/git2/types.h +4 -89
  142. data/vendor/libgit2/include/git2/version.h +4 -4
  143. data/vendor/libgit2/include/git2/worktree.h +5 -5
  144. data/vendor/libgit2/src/CMakeLists.txt +89 -224
  145. data/vendor/libgit2/src/alloc.c +2 -14
  146. data/vendor/libgit2/src/{stdalloc.c → allocators/stdalloc.c} +3 -4
  147. data/vendor/libgit2/src/{stdalloc.h → allocators/stdalloc.h} +4 -4
  148. data/vendor/libgit2/src/allocators/win32_crtdbg.c +118 -0
  149. data/vendor/libgit2/src/{transports/cred.h → allocators/win32_crtdbg.h} +5 -4
  150. data/vendor/libgit2/src/apply.c +31 -15
  151. data/vendor/libgit2/src/attr.c +70 -64
  152. data/vendor/libgit2/src/attr_file.c +189 -96
  153. data/vendor/libgit2/src/attr_file.h +9 -9
  154. data/vendor/libgit2/src/attrcache.c +47 -47
  155. data/vendor/libgit2/src/attrcache.h +2 -1
  156. data/vendor/libgit2/src/blame.c +17 -5
  157. data/vendor/libgit2/src/blame.h +1 -1
  158. data/vendor/libgit2/src/blame_git.c +21 -7
  159. data/vendor/libgit2/src/blob.c +81 -17
  160. data/vendor/libgit2/src/blob.h +2 -2
  161. data/vendor/libgit2/src/branch.c +60 -32
  162. data/vendor/libgit2/src/buffer.c +5 -0
  163. data/vendor/libgit2/src/buffer.h +1 -0
  164. data/vendor/libgit2/src/cache.c +26 -33
  165. data/vendor/libgit2/src/cache.h +1 -1
  166. data/vendor/libgit2/src/cc-compat.h +5 -0
  167. data/vendor/libgit2/src/checkout.c +26 -16
  168. data/vendor/libgit2/src/cherrypick.c +7 -1
  169. data/vendor/libgit2/src/clone.c +29 -7
  170. data/vendor/libgit2/src/clone.h +4 -0
  171. data/vendor/libgit2/src/commit.c +70 -22
  172. data/vendor/libgit2/src/commit.h +6 -0
  173. data/vendor/libgit2/src/commit_list.c +28 -76
  174. data/vendor/libgit2/src/commit_list.h +2 -2
  175. data/vendor/libgit2/src/common.h +3 -75
  176. data/vendor/libgit2/src/config.c +31 -40
  177. data/vendor/libgit2/src/config.h +7 -6
  178. data/vendor/libgit2/src/config_backend.h +12 -0
  179. data/vendor/libgit2/src/config_cache.c +39 -39
  180. data/vendor/libgit2/src/config_entries.c +69 -99
  181. data/vendor/libgit2/src/config_entries.h +1 -0
  182. data/vendor/libgit2/src/config_file.c +337 -380
  183. data/vendor/libgit2/src/config_mem.c +12 -16
  184. data/vendor/libgit2/src/config_parse.c +49 -29
  185. data/vendor/libgit2/src/config_parse.h +13 -12
  186. data/vendor/libgit2/src/config_snapshot.c +206 -0
  187. data/vendor/libgit2/src/crlf.c +14 -14
  188. data/vendor/libgit2/src/describe.c +21 -20
  189. data/vendor/libgit2/src/diff.c +43 -66
  190. data/vendor/libgit2/src/diff.h +4 -3
  191. data/vendor/libgit2/src/diff_driver.c +37 -38
  192. data/vendor/libgit2/src/diff_file.c +12 -10
  193. data/vendor/libgit2/src/diff_file.h +2 -2
  194. data/vendor/libgit2/src/diff_generate.c +26 -26
  195. data/vendor/libgit2/src/diff_generate.h +2 -2
  196. data/vendor/libgit2/src/diff_parse.c +1 -1
  197. data/vendor/libgit2/src/diff_print.c +25 -13
  198. data/vendor/libgit2/src/diff_stats.c +1 -1
  199. data/vendor/libgit2/src/diff_tform.c +11 -11
  200. data/vendor/libgit2/src/errors.c +21 -25
  201. data/vendor/libgit2/src/errors.h +81 -0
  202. data/vendor/libgit2/src/features.h.in +9 -2
  203. data/vendor/libgit2/src/fetch.c +7 -2
  204. data/vendor/libgit2/src/fetchhead.c +9 -9
  205. data/vendor/libgit2/src/filebuf.c +1 -1
  206. data/vendor/libgit2/src/filebuf.h +1 -1
  207. data/vendor/libgit2/src/filter.c +16 -8
  208. data/vendor/libgit2/src/{fileops.c → futils.c} +20 -17
  209. data/vendor/libgit2/src/{fileops.h → futils.h} +5 -5
  210. data/vendor/libgit2/src/hash.c +61 -0
  211. data/vendor/libgit2/src/hash.h +19 -21
  212. data/vendor/libgit2/src/hash/sha1.h +38 -0
  213. data/vendor/libgit2/src/hash/{hash_collisiondetect.h → sha1/collisiondetect.c} +14 -17
  214. data/vendor/libgit2/src/hash/sha1/collisiondetect.h +19 -0
  215. data/vendor/libgit2/src/hash/{hash_common_crypto.h → sha1/common_crypto.c} +15 -19
  216. data/vendor/libgit2/src/hash/sha1/common_crypto.h +19 -0
  217. data/vendor/libgit2/src/hash/{hash_generic.c → sha1/generic.c} +22 -10
  218. data/vendor/libgit2/src/hash/{hash_generic.h → sha1/generic.h} +4 -14
  219. data/vendor/libgit2/src/hash/{hash_mbedtls.c → sha1/mbedtls.c} +15 -7
  220. data/vendor/libgit2/src/hash/{hash_mbedtls.h → sha1/mbedtls.h} +6 -11
  221. data/vendor/libgit2/src/hash/{hash_openssl.h → sha1/openssl.c} +14 -18
  222. data/vendor/libgit2/src/hash/sha1/openssl.h +19 -0
  223. data/vendor/libgit2/src/hash/{sha1dc → sha1/sha1dc}/sha1.c +14 -3
  224. data/vendor/libgit2/src/hash/{sha1dc → sha1/sha1dc}/sha1.h +0 -0
  225. data/vendor/libgit2/src/hash/{sha1dc → sha1/sha1dc}/ubc_check.c +0 -0
  226. data/vendor/libgit2/src/hash/{sha1dc → sha1/sha1dc}/ubc_check.h +0 -0
  227. data/vendor/libgit2/src/hash/{hash_win32.c → sha1/win32.c} +34 -24
  228. data/vendor/libgit2/src/hash/{hash_win32.h → sha1/win32.h} +6 -19
  229. data/vendor/libgit2/src/hashsig.c +1 -1
  230. data/vendor/libgit2/src/idxmap.c +91 -65
  231. data/vendor/libgit2/src/idxmap.h +151 -15
  232. data/vendor/libgit2/src/ignore.c +26 -35
  233. data/vendor/libgit2/src/index.c +103 -81
  234. data/vendor/libgit2/src/index.h +1 -1
  235. data/vendor/libgit2/src/indexer.c +69 -70
  236. data/vendor/libgit2/src/integer.h +11 -4
  237. data/vendor/libgit2/src/iterator.c +32 -28
  238. data/vendor/libgit2/src/iterator.h +8 -8
  239. data/vendor/libgit2/src/map.h +1 -1
  240. data/vendor/libgit2/src/merge.c +55 -41
  241. data/vendor/libgit2/src/merge.h +2 -2
  242. data/vendor/libgit2/src/merge_driver.c +5 -5
  243. data/vendor/libgit2/src/merge_file.c +1 -1
  244. data/vendor/libgit2/src/mwindow.c +18 -23
  245. data/vendor/libgit2/src/mwindow.h +4 -4
  246. data/vendor/libgit2/src/net.c +411 -0
  247. data/vendor/libgit2/src/net.h +57 -0
  248. data/vendor/libgit2/src/netops.c +6 -222
  249. data/vendor/libgit2/src/netops.h +1 -37
  250. data/vendor/libgit2/src/notes.c +2 -2
  251. data/vendor/libgit2/src/object.c +3 -3
  252. data/vendor/libgit2/src/object.h +2 -0
  253. data/vendor/libgit2/src/odb.c +41 -23
  254. data/vendor/libgit2/src/odb.h +3 -2
  255. data/vendor/libgit2/src/odb_loose.c +17 -10
  256. data/vendor/libgit2/src/odb_mempack.c +13 -24
  257. data/vendor/libgit2/src/odb_pack.c +4 -4
  258. data/vendor/libgit2/src/offmap.c +43 -55
  259. data/vendor/libgit2/src/offmap.h +102 -24
  260. data/vendor/libgit2/src/oid.c +19 -8
  261. data/vendor/libgit2/src/oidmap.c +39 -57
  262. data/vendor/libgit2/src/oidmap.h +99 -19
  263. data/vendor/libgit2/src/pack-objects.c +25 -32
  264. data/vendor/libgit2/src/pack-objects.h +1 -1
  265. data/vendor/libgit2/src/pack.c +97 -129
  266. data/vendor/libgit2/src/pack.h +15 -18
  267. data/vendor/libgit2/src/parse.c +10 -0
  268. data/vendor/libgit2/src/parse.h +3 -3
  269. data/vendor/libgit2/src/patch.c +1 -1
  270. data/vendor/libgit2/src/patch_generate.c +1 -1
  271. data/vendor/libgit2/src/patch_parse.c +30 -9
  272. data/vendor/libgit2/src/path.c +43 -6
  273. data/vendor/libgit2/src/path.h +2 -0
  274. data/vendor/libgit2/src/pathspec.c +14 -14
  275. data/vendor/libgit2/src/pool.c +26 -22
  276. data/vendor/libgit2/src/pool.h +7 -7
  277. data/vendor/libgit2/src/posix.c +7 -7
  278. data/vendor/libgit2/src/posix.h +12 -1
  279. data/vendor/libgit2/src/proxy.c +7 -2
  280. data/vendor/libgit2/src/push.c +10 -5
  281. data/vendor/libgit2/src/reader.c +2 -2
  282. data/vendor/libgit2/src/rebase.c +87 -28
  283. data/vendor/libgit2/src/refdb.c +12 -0
  284. data/vendor/libgit2/src/refdb_fs.c +215 -169
  285. data/vendor/libgit2/src/reflog.c +11 -13
  286. data/vendor/libgit2/src/refs.c +34 -23
  287. data/vendor/libgit2/src/refs.h +8 -1
  288. data/vendor/libgit2/src/refspec.c +9 -16
  289. data/vendor/libgit2/src/regexp.c +221 -0
  290. data/vendor/libgit2/src/regexp.h +97 -0
  291. data/vendor/libgit2/src/remote.c +57 -55
  292. data/vendor/libgit2/src/remote.h +2 -2
  293. data/vendor/libgit2/src/repository.c +120 -103
  294. data/vendor/libgit2/src/repository.h +49 -40
  295. data/vendor/libgit2/src/revert.c +6 -1
  296. data/vendor/libgit2/src/revparse.c +18 -19
  297. data/vendor/libgit2/src/revwalk.c +71 -33
  298. data/vendor/libgit2/src/revwalk.h +20 -0
  299. data/vendor/libgit2/src/settings.c +13 -1
  300. data/vendor/libgit2/src/sortedcache.c +12 -26
  301. data/vendor/libgit2/src/sortedcache.h +1 -1
  302. data/vendor/libgit2/src/stash.c +45 -65
  303. data/vendor/libgit2/src/status.c +17 -11
  304. data/vendor/libgit2/src/streams/openssl.c +53 -1
  305. data/vendor/libgit2/src/streams/socket.c +2 -2
  306. data/vendor/libgit2/src/strmap.c +37 -84
  307. data/vendor/libgit2/src/strmap.h +105 -33
  308. data/vendor/libgit2/src/submodule.c +151 -126
  309. data/vendor/libgit2/src/submodule.h +1 -1
  310. data/vendor/libgit2/src/tag.c +10 -2
  311. data/vendor/libgit2/src/trace.c +1 -1
  312. data/vendor/libgit2/src/trace.h +3 -3
  313. data/vendor/libgit2/src/trailer.c +46 -32
  314. data/vendor/libgit2/src/transaction.c +3 -8
  315. data/vendor/libgit2/src/transports/auth.c +16 -15
  316. data/vendor/libgit2/src/transports/auth.h +18 -11
  317. data/vendor/libgit2/src/transports/auth_negotiate.c +64 -33
  318. data/vendor/libgit2/src/transports/auth_negotiate.h +2 -2
  319. data/vendor/libgit2/src/transports/auth_ntlm.c +223 -0
  320. data/vendor/libgit2/src/transports/auth_ntlm.h +38 -0
  321. data/vendor/libgit2/src/transports/credential.c +476 -0
  322. data/vendor/libgit2/src/transports/{cred_helpers.c → credential_helpers.c} +21 -8
  323. data/vendor/libgit2/src/transports/git.c +11 -16
  324. data/vendor/libgit2/src/transports/http.c +488 -1248
  325. data/vendor/libgit2/src/transports/http.h +4 -1
  326. data/vendor/libgit2/src/transports/httpclient.c +1526 -0
  327. data/vendor/libgit2/src/transports/httpclient.h +190 -0
  328. data/vendor/libgit2/src/transports/local.c +10 -10
  329. data/vendor/libgit2/src/transports/smart.c +19 -19
  330. data/vendor/libgit2/src/transports/smart.h +3 -3
  331. data/vendor/libgit2/src/transports/smart_protocol.c +40 -64
  332. data/vendor/libgit2/src/transports/ssh.c +77 -59
  333. data/vendor/libgit2/src/transports/winhttp.c +266 -241
  334. data/vendor/libgit2/src/tree-cache.c +14 -7
  335. data/vendor/libgit2/src/tree.c +16 -26
  336. data/vendor/libgit2/src/unix/map.c +1 -1
  337. data/vendor/libgit2/src/unix/posix.h +2 -12
  338. data/vendor/libgit2/src/userdiff.h +3 -1
  339. data/vendor/libgit2/src/util.c +51 -53
  340. data/vendor/libgit2/src/util.h +16 -21
  341. data/vendor/libgit2/src/wildmatch.c +320 -0
  342. data/vendor/libgit2/src/wildmatch.h +23 -0
  343. data/vendor/libgit2/src/win32/map.c +3 -5
  344. data/vendor/libgit2/src/win32/path_w32.c +12 -2
  345. data/vendor/libgit2/src/win32/path_w32.h +0 -29
  346. data/vendor/libgit2/src/win32/posix.h +1 -4
  347. data/vendor/libgit2/src/win32/posix_w32.c +48 -5
  348. data/vendor/libgit2/src/win32/precompiled.h +0 -2
  349. data/vendor/libgit2/src/win32/thread.c +5 -5
  350. data/vendor/libgit2/src/win32/w32_buffer.c +7 -3
  351. data/vendor/libgit2/src/win32/w32_common.h +39 -0
  352. data/vendor/libgit2/src/win32/w32_crtdbg_stacktrace.c +0 -93
  353. data/vendor/libgit2/src/win32/w32_crtdbg_stacktrace.h +0 -2
  354. data/vendor/libgit2/src/win32/w32_stack.c +4 -9
  355. data/vendor/libgit2/src/win32/w32_stack.h +3 -3
  356. data/vendor/libgit2/src/win32/w32_util.c +31 -0
  357. data/vendor/libgit2/src/win32/w32_util.h +6 -32
  358. data/vendor/libgit2/src/worktree.c +36 -22
  359. data/vendor/libgit2/src/xdiff/xdiffi.c +1 -1
  360. data/vendor/libgit2/src/xdiff/xmerge.c +12 -0
  361. data/vendor/libgit2/src/xdiff/xpatience.c +3 -0
  362. data/vendor/libgit2/src/zstream.c +5 -0
  363. data/vendor/libgit2/src/zstream.h +1 -0
  364. metadata +108 -38
  365. data/vendor/libgit2/deps/regex/CMakeLists.txt +0 -2
  366. data/vendor/libgit2/deps/regex/COPYING +0 -502
  367. data/vendor/libgit2/deps/regex/config.h +0 -7
  368. data/vendor/libgit2/deps/regex/regcomp.c +0 -3857
  369. data/vendor/libgit2/deps/regex/regex.c +0 -92
  370. data/vendor/libgit2/deps/regex/regex.h +0 -582
  371. data/vendor/libgit2/deps/regex/regex_internal.c +0 -1744
  372. data/vendor/libgit2/deps/regex/regex_internal.h +0 -819
  373. data/vendor/libgit2/deps/regex/regexec.c +0 -4369
  374. data/vendor/libgit2/include/git2/inttypes.h +0 -309
  375. data/vendor/libgit2/include/git2/sys/time.h +0 -31
  376. data/vendor/libgit2/libgit2.pc.in +0 -13
  377. data/vendor/libgit2/src/fnmatch.c +0 -248
  378. data/vendor/libgit2/src/fnmatch.h +0 -48
  379. data/vendor/libgit2/src/transports/cred.c +0 -390
@@ -11,6 +11,7 @@ typedef struct config_entry_list {
11
11
  struct config_entry_list *next;
12
12
  struct config_entry_list *last;
13
13
  git_config_entry *entry;
14
+ bool first;
14
15
  } config_entry_list;
15
16
 
16
17
  typedef struct config_entries_iterator {
@@ -25,31 +26,6 @@ struct git_config_entries {
25
26
  config_entry_list *list;
26
27
  };
27
28
 
28
- static void config_entry_list_free(config_entry_list *list)
29
- {
30
- config_entry_list *next;
31
-
32
- while (list != NULL) {
33
- next = list->next;
34
-
35
- git__free((char*) list->entry->name);
36
- git__free((char *) list->entry->value);
37
- git__free(list->entry);
38
- git__free(list);
39
-
40
- list = next;
41
- };
42
- }
43
-
44
- static void config_entry_list_append(config_entry_list **list, config_entry_list *entry)
45
- {
46
- if (*list)
47
- (*list)->last->next = entry;
48
- else
49
- *list = entry;
50
- (*list)->last = entry;
51
- }
52
-
53
29
  int git_config_entries_new(git_config_entries **out)
54
30
  {
55
31
  git_config_entries *entries;
@@ -59,7 +35,7 @@ int git_config_entries_new(git_config_entries **out)
59
35
  GIT_ERROR_CHECK_ALLOC(entries);
60
36
  GIT_REFCOUNT_INC(entries);
61
37
 
62
- if ((error = git_strmap_alloc(&entries->map)) < 0)
38
+ if ((error = git_strmap_new(&entries->map)) < 0)
63
39
  git__free(entries);
64
40
  else
65
41
  *out = entries;
@@ -67,6 +43,36 @@ int git_config_entries_new(git_config_entries **out)
67
43
  return error;
68
44
  }
69
45
 
46
+ int git_config_entries_dup_entry(git_config_entries *entries, const git_config_entry *entry)
47
+ {
48
+ git_config_entry *duplicated;
49
+ int error;
50
+
51
+ duplicated = git__calloc(1, sizeof(git_config_entry));
52
+ GIT_ERROR_CHECK_ALLOC(duplicated);
53
+
54
+ duplicated->name = git__strdup(entry->name);
55
+ GIT_ERROR_CHECK_ALLOC(duplicated->name);
56
+
57
+ if (entry->value) {
58
+ duplicated->value = git__strdup(entry->value);
59
+ GIT_ERROR_CHECK_ALLOC(duplicated->value);
60
+ }
61
+ duplicated->level = entry->level;
62
+ duplicated->include_depth = entry->include_depth;
63
+
64
+ if ((error = git_config_entries_append(entries, duplicated)) < 0)
65
+ goto out;
66
+
67
+ out:
68
+ if (error && duplicated) {
69
+ git__free((char *) duplicated->name);
70
+ git__free((char *) duplicated->value);
71
+ git__free(duplicated);
72
+ }
73
+ return error;
74
+ }
75
+
70
76
  int git_config_entries_dup(git_config_entries **out, git_config_entries *entries)
71
77
  {
72
78
  git_config_entries *result = NULL;
@@ -76,22 +82,9 @@ int git_config_entries_dup(git_config_entries **out, git_config_entries *entries
76
82
  if ((error = git_config_entries_new(&result)) < 0)
77
83
  goto out;
78
84
 
79
- for (head = entries->list; head; head = head->next) {
80
- git_config_entry *dup;
81
-
82
- dup = git__calloc(1, sizeof(git_config_entry));
83
- dup->name = git__strdup(head->entry->name);
84
- GIT_ERROR_CHECK_ALLOC(dup->name);
85
- if (head->entry->value) {
86
- dup->value = git__strdup(head->entry->value);
87
- GIT_ERROR_CHECK_ALLOC(dup->value);
88
- }
89
- dup->level = head->entry->level;
90
- dup->include_depth = head->entry->include_depth;
91
-
92
- if ((error = git_config_entries_append(result, dup)) < 0)
85
+ for (head = entries->list; head; head = head->next)
86
+ if ((git_config_entries_dup_entry(result, head->entry)) < 0)
93
87
  goto out;
94
- }
95
88
 
96
89
  *out = result;
97
90
  result = NULL;
@@ -110,12 +103,15 @@ static void config_entries_free(git_config_entries *entries)
110
103
  {
111
104
  config_entry_list *list = NULL, *next;
112
105
 
113
- git_strmap_foreach_value(entries->map, list, config_entry_list_free(list));
114
106
  git_strmap_free(entries->map);
115
107
 
116
108
  list = entries->list;
117
109
  while (list != NULL) {
118
110
  next = list->next;
111
+ if (list->first)
112
+ git__free((char *) list->entry->name);
113
+ git__free((char *) list->entry->value);
114
+ git__free(list->entry);
119
115
  git__free(list);
120
116
  list = next;
121
117
  }
@@ -131,55 +127,33 @@ void git_config_entries_free(git_config_entries *entries)
131
127
 
132
128
  int git_config_entries_append(git_config_entries *entries, git_config_entry *entry)
133
129
  {
134
- config_entry_list *existing, *var;
135
- int error = 0;
136
- size_t pos;
137
-
138
- var = git__calloc(1, sizeof(config_entry_list));
139
- GIT_ERROR_CHECK_ALLOC(var);
140
- var->entry = entry;
141
-
142
- pos = git_strmap_lookup_index(entries->map, entry->name);
143
- if (!git_strmap_valid_index(entries->map, pos)) {
144
- /*
145
- * We only ever inspect `last` from the first config
146
- * entry in a multivar. In case where this new entry is
147
- * the first one in the entry map, it will also be the
148
- * last one at the time of adding it, which is
149
- * why we set `last` here to itself. Otherwise we
150
- * do not have to set `last` and leave it set to
151
- * `NULL`.
152
- */
153
- var->last = var;
154
-
155
- git_strmap_insert(entries->map, entry->name, var, &error);
156
-
157
- if (error > 0)
158
- error = 0;
130
+ config_entry_list *existing, *head;
131
+
132
+ head = git__calloc(1, sizeof(config_entry_list));
133
+ GIT_ERROR_CHECK_ALLOC(head);
134
+ head->entry = entry;
135
+
136
+ /*
137
+ * This is a micro-optimization for configuration files
138
+ * with a lot of same keys. As for multivars the entry's
139
+ * key will be the same for all entries, we can just free
140
+ * all except the first entry's name and just re-use it.
141
+ */
142
+ if ((existing = git_strmap_get(entries->map, entry->name)) != NULL) {
143
+ git__free((char *) entry->name);
144
+ entry->name = existing->entry->name;
159
145
  } else {
160
- existing = git_strmap_value_at(entries->map, pos);
161
- config_entry_list_append(&existing, var);
146
+ head->first = 1;
162
147
  }
163
148
 
164
- var = git__calloc(1, sizeof(config_entry_list));
165
- GIT_ERROR_CHECK_ALLOC(var);
166
- var->entry = entry;
167
- config_entry_list_append(&entries->list, var);
168
-
169
- return error;
170
- }
171
-
172
- int config_entry_get(config_entry_list **out, git_config_entries *entries, const char *key)
173
- {
174
- size_t pos;
175
-
176
- pos = git_strmap_lookup_index(entries->map, key);
177
-
178
- /* no error message; the config system will write one */
179
- if (!git_strmap_valid_index(entries->map, pos))
180
- return GIT_ENOTFOUND;
149
+ if (entries->list)
150
+ entries->list->last->next = head;
151
+ else
152
+ entries->list = head;
153
+ entries->list->last = head;
181
154
 
182
- *out = git_strmap_value_at(entries->map, pos);
155
+ if (git_strmap_set(entries->map, entry->name, head) < 0)
156
+ return -1;
183
157
 
184
158
  return 0;
185
159
  }
@@ -187,24 +161,20 @@ int config_entry_get(config_entry_list **out, git_config_entries *entries, const
187
161
  int git_config_entries_get(git_config_entry **out, git_config_entries *entries, const char *key)
188
162
  {
189
163
  config_entry_list *entry;
190
- int error;
191
-
192
- if ((error = config_entry_get(&entry, entries, key)) < 0)
193
- return error;
194
- *out = entry->last->entry;
195
-
164
+ if ((entry = git_strmap_get(entries->map, key)) == NULL)
165
+ return GIT_ENOTFOUND;
166
+ *out = entry->entry;
196
167
  return 0;
197
168
  }
198
169
 
199
170
  int git_config_entries_get_unique(git_config_entry **out, git_config_entries *entries, const char *key)
200
171
  {
201
172
  config_entry_list *entry;
202
- int error;
203
173
 
204
- if ((error = config_entry_get(&entry, entries, key)) < 0)
205
- return error;
174
+ if ((entry = git_strmap_get(entries->map, key)) == NULL)
175
+ return GIT_ENOTFOUND;
206
176
 
207
- if (entry->next != NULL) {
177
+ if (!entry->first) {
208
178
  git_error_set(GIT_ERROR_CONFIG, "entry is not unique due to being a multivar");
209
179
  return -1;
210
180
  }
@@ -219,14 +189,14 @@ int git_config_entries_get_unique(git_config_entry **out, git_config_entries *en
219
189
  return 0;
220
190
  }
221
191
 
222
- void config_iterator_free(git_config_iterator *iter)
192
+ static void config_iterator_free(git_config_iterator *iter)
223
193
  {
224
194
  config_entries_iterator *it = (config_entries_iterator *) iter;
225
195
  git_config_entries_free(it->entries);
226
196
  git__free(it);
227
197
  }
228
198
 
229
- int config_iterator_next(
199
+ static int config_iterator_next(
230
200
  git_config_entry **entry,
231
201
  git_config_iterator *iter)
232
202
  {
@@ -14,6 +14,7 @@ typedef struct git_config_entries git_config_entries;
14
14
 
15
15
  int git_config_entries_new(git_config_entries **out);
16
16
  int git_config_entries_dup(git_config_entries **out, git_config_entries *entries);
17
+ int git_config_entries_dup_entry(git_config_entries *entries, const git_config_entry *entry);
17
18
  void git_config_entries_incref(git_config_entries *entries);
18
19
  void git_config_entries_free(git_config_entries *entries);
19
20
  /* Add or append the new config option */
@@ -7,36 +7,35 @@
7
7
 
8
8
  #include "config.h"
9
9
 
10
- #include "filebuf.h"
11
- #include "sysdir.h"
12
- #include "buffer.h"
13
- #include "buf_text.h"
14
10
  #include "git2/config.h"
15
11
  #include "git2/sys/config.h"
16
- #include "git2/types.h"
17
- #include "strmap.h"
12
+
18
13
  #include "array.h"
19
- #include "config_parse.h"
14
+ #include "buffer.h"
15
+ #include "config_backend.h"
20
16
  #include "config_entries.h"
21
-
22
- #include <ctype.h>
23
- #include <sys/types.h>
24
- #include <regex.h>
17
+ #include "config_parse.h"
18
+ #include "filebuf.h"
19
+ #include "regexp.h"
20
+ #include "sysdir.h"
21
+ #include "wildmatch.h"
25
22
 
26
23
  /* Max depth for [include] directives */
27
24
  #define MAX_INCLUDE_DEPTH 10
28
25
 
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;
32
+
29
33
  typedef struct {
30
34
  git_config_backend parent;
31
- /* mutex to coordinate accessing the values */
32
35
  git_mutex values_mutex;
33
36
  git_config_entries *entries;
34
37
  const git_repository *repo;
35
38
  git_config_level_t level;
36
- } diskfile_header;
37
-
38
- typedef struct {
39
- diskfile_header header;
40
39
 
41
40
  git_array_t(git_config_parser) readers;
42
41
 
@@ -44,60 +43,47 @@ typedef struct {
44
43
  git_filebuf locked_buf;
45
44
  git_buf locked_content;
46
45
 
47
- struct config_file file;
48
- } diskfile_backend;
49
-
50
- typedef struct {
51
- diskfile_header header;
52
-
53
- diskfile_backend *snapshot_from;
54
- } diskfile_readonly_backend;
46
+ config_file file;
47
+ } config_file_backend;
55
48
 
56
49
  typedef struct {
57
50
  const git_repository *repo;
58
- const char *file_path;
51
+ config_file *file;
59
52
  git_config_entries *entries;
60
53
  git_config_level_t level;
61
54
  unsigned int depth;
62
- } diskfile_parse_state;
55
+ } config_file_parse_data;
63
56
 
64
- static int config_read(git_config_entries *entries, const git_repository *repo, git_config_file *file, git_config_level_t level, int depth);
65
- 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);
66
60
  static char *escape_value(const char *ptr);
67
61
 
68
- static int config_snapshot(git_config_backend **out, git_config_backend *in);
69
-
70
- static int config_error_readonly(void)
71
- {
72
- git_error_set(GIT_ERROR_CONFIG, "this backend is read-only");
73
- return -1;
74
- }
75
-
76
62
  /**
77
63
  * Take the current values map from the backend and increase its
78
64
  * refcount. This is its own function to make sure we use the mutex to
79
65
  * avoid the map pointer from changing under us.
80
66
  */
81
- static git_config_entries *diskfile_entries_take(diskfile_header *h)
67
+ static int config_file_entries_take(git_config_entries **out, config_file_backend *b)
82
68
  {
83
- git_config_entries *entries;
69
+ int error;
84
70
 
85
- if (git_mutex_lock(&h->values_mutex) < 0) {
86
- git_error_set(GIT_ERROR_OS, "failed to lock config backend");
87
- return NULL;
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;
88
74
  }
89
75
 
90
- entries = h->entries;
91
- git_config_entries_incref(entries);
76
+ git_config_entries_incref(b->entries);
77
+ *out = b->entries;
92
78
 
93
- git_mutex_unlock(&h->values_mutex);
79
+ git_mutex_unlock(&b->values_mutex);
94
80
 
95
- return entries;
81
+ return 0;
96
82
  }
97
83
 
98
- static void config_file_clear(struct config_file *file)
84
+ static void config_file_clear(config_file *file)
99
85
  {
100
- struct config_file *include;
86
+ config_file *include;
101
87
  uint32_t i;
102
88
 
103
89
  if (file == NULL)
@@ -111,31 +97,31 @@ static void config_file_clear(struct config_file *file)
111
97
  git__free(file->path);
112
98
  }
113
99
 
114
- 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)
115
101
  {
102
+ config_file_backend *b = GIT_CONTAINER_OF(cfg, config_file_backend, parent);
116
103
  int res;
117
- diskfile_backend *b = (diskfile_backend *)cfg;
118
104
 
119
- b->header.level = level;
120
- b->header.repo = repo;
105
+ b->level = level;
106
+ b->repo = repo;
121
107
 
122
- if ((res = git_config_entries_new(&b->header.entries)) < 0)
108
+ if ((res = git_config_entries_new(&b->entries)) < 0)
123
109
  return res;
124
110
 
125
111
  if (!git_path_exists(b->file.path))
126
112
  return 0;
127
113
 
128
- if (res < 0 || (res = config_read(b->header.entries, repo, &b->file, level, 0)) < 0) {
129
- git_config_entries_free(b->header.entries);
130
- 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;
131
117
  }
132
118
 
133
119
  return res;
134
120
  }
135
121
 
136
- static int config_is_modified(int *modified, struct config_file *file)
122
+ static int config_file_is_modified(int *modified, config_file *file)
137
123
  {
138
- git_config_file *include;
124
+ config_file *include;
139
125
  git_buf buf = GIT_BUF_INIT;
140
126
  git_oid hash;
141
127
  uint32_t i;
@@ -143,6 +129,9 @@ static int config_is_modified(int *modified, struct config_file *file)
143
129
 
144
130
  *modified = 0;
145
131
 
132
+ if (!git_futils_filestamp_check(&file->stamp, file->path))
133
+ goto check_includes;
134
+
146
135
  if ((error = git_futils_readbuffer(&buf, file->path)) < 0)
147
136
  goto out;
148
137
 
@@ -154,8 +143,9 @@ static int config_is_modified(int *modified, struct config_file *file)
154
143
  goto out;
155
144
  }
156
145
 
146
+ check_includes:
157
147
  git_array_foreach(file->includes, i, include) {
158
- if ((error = config_is_modified(modified, include)) < 0 || *modified)
148
+ if ((error = config_file_is_modified(modified, include)) < 0 || *modified)
159
149
  goto out;
160
150
  }
161
151
 
@@ -165,89 +155,125 @@ out:
165
155
  return error;
166
156
  }
167
157
 
168
- static int config_refresh(git_config_backend *cfg)
158
+ static int config_file_set_entries(git_config_backend *cfg, git_config_entries *entries)
169
159
  {
170
- diskfile_backend *b = (diskfile_backend *)cfg;
171
- git_config_entries *entries = NULL, *tmp;
172
- git_config_file *include;
173
- 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;
174
164
  uint32_t i;
175
165
 
176
- if (b->header.parent.readonly)
177
- 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
+ }
170
+
171
+ git_array_foreach(b->file.includes, i, include)
172
+ config_file_clear(include);
173
+ git_array_clear(b->file.includes);
178
174
 
179
- error = config_is_modified(&modified, &b->file);
180
- if (error < 0 && error != GIT_ENOTFOUND)
175
+ if ((error = git_mutex_lock(&b->values_mutex)) < 0) {
176
+ git_error_set(GIT_ERROR_OS, "failed to lock config backend");
181
177
  goto out;
178
+ }
182
179
 
183
- if (!modified)
184
- return 0;
180
+ old = b->entries;
181
+ b->entries = entries;
185
182
 
186
- if ((error = git_config_entries_new(&entries)) < 0)
187
- goto out;
183
+ git_mutex_unlock(&b->values_mutex);
188
184
 
189
- /* Reparse the current configuration */
190
- git_array_foreach(b->file.includes, i, include) {
191
- config_file_clear(include);
192
- }
193
- git_array_clear(b->file.includes);
185
+ out:
186
+ git_config_entries_free(old);
187
+ return error;
188
+ }
194
189
 
195
- 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)
196
200
  goto out;
197
201
 
198
- if ((error = git_mutex_lock(&b->header.values_mutex)) < 0) {
199
- git_error_set(GIT_ERROR_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)
200
218
  goto out;
201
- }
202
219
 
203
- tmp = b->header.entries;
204
- b->header.entries = entries;
205
- entries = tmp;
220
+ if (!modified)
221
+ return 0;
206
222
 
207
- 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;
208
227
 
228
+ entries = NULL;
209
229
  out:
210
230
  git_config_entries_free(entries);
211
231
 
212
232
  return (error == GIT_ENOTFOUND) ? 0 : error;
213
233
  }
214
234
 
215
- static void backend_free(git_config_backend *_backend)
235
+ static void config_file_free(git_config_backend *_backend)
216
236
  {
217
- diskfile_backend *backend = (diskfile_backend *)_backend;
237
+ config_file_backend *backend = GIT_CONTAINER_OF(_backend, config_file_backend, parent);
218
238
 
219
239
  if (backend == NULL)
220
240
  return;
221
241
 
222
242
  config_file_clear(&backend->file);
223
- git_config_entries_free(backend->header.entries);
224
- git_mutex_free(&backend->header.values_mutex);
243
+ git_config_entries_free(backend->entries);
244
+ git_mutex_free(&backend->values_mutex);
225
245
  git__free(backend);
226
246
  }
227
247
 
228
- static int config_iterator_new(
248
+ static int config_file_iterator(
229
249
  git_config_iterator **iter,
230
- struct git_config_backend* backend)
250
+ struct git_config_backend *backend)
231
251
  {
232
- diskfile_header *bh = (diskfile_header *) backend;
233
- git_config_entries *entries;
252
+ config_file_backend *b = GIT_CONTAINER_OF(backend, config_file_backend, parent);
253
+ git_config_entries *dupped = NULL, *entries = NULL;
234
254
  int error;
235
255
 
236
- if ((error = git_config_entries_dup(&entries, bh->entries)) < 0)
237
- return error;
238
-
239
- if ((error = git_config_entries_iterator_new(iter, entries)) < 0)
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)
240
260
  goto out;
241
261
 
242
262
  out:
243
263
  /* Let iterator delete duplicated entries when it's done */
244
264
  git_config_entries_free(entries);
265
+ git_config_entries_free(dupped);
245
266
  return error;
246
267
  }
247
268
 
248
- static int config_set(git_config_backend *cfg, const char *name, const char *value)
269
+ static int config_file_snapshot(git_config_backend **out, git_config_backend *backend)
249
270
  {
250
- diskfile_backend *b = (diskfile_backend *)cfg;
271
+ return git_config_backend_snapshot(out, backend);
272
+ }
273
+
274
+ static int config_file_set(git_config_backend *cfg, const char *name, const char *value)
275
+ {
276
+ config_file_backend *b = GIT_CONTAINER_OF(cfg, config_file_backend, parent);
251
277
  git_config_entries *entries;
252
278
  git_config_entry *existing;
253
279
  char *key, *esc_value = NULL;
@@ -256,8 +282,8 @@ static int config_set(git_config_backend *cfg, const char *name, const char *val
256
282
  if ((error = git_config__normalize_name(name, &key)) < 0)
257
283
  return error;
258
284
 
259
- if ((entries = diskfile_entries_take(&b->header)) == NULL)
260
- return -1;
285
+ if ((error = config_file_entries_take(&entries, b)) < 0)
286
+ return error;
261
287
 
262
288
  /* Check whether we'd be modifying an included or multivar key */
263
289
  if ((error = git_config_entries_get_unique(&existing, entries, key)) < 0) {
@@ -277,11 +303,9 @@ static int config_set(git_config_backend *cfg, const char *name, const char *val
277
303
  GIT_ERROR_CHECK_ALLOC(esc_value);
278
304
  }
279
305
 
280
- if ((error = config_write(b, name, key, NULL, esc_value)) < 0)
306
+ if ((error = config_file_write(b, name, key, NULL, esc_value)) < 0)
281
307
  goto out;
282
308
 
283
- error = config_refresh(cfg);
284
-
285
309
  out:
286
310
  git_config_entries_free(entries);
287
311
  git__free(esc_value);
@@ -290,7 +314,7 @@ out:
290
314
  }
291
315
 
292
316
  /* release the map containing the entry as an equivalent to freeing it */
293
- static void free_diskfile_entry(git_config_entry *entry)
317
+ static void config_file_entry_free(git_config_entry *entry)
294
318
  {
295
319
  git_config_entries *entries = (git_config_entries *) entry->payload;
296
320
  git_config_entries_free(entries);
@@ -299,67 +323,61 @@ static void free_diskfile_entry(git_config_entry *entry)
299
323
  /*
300
324
  * Internal function that actually gets the value in string form
301
325
  */
302
- 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)
303
327
  {
304
- diskfile_header *h = (diskfile_header *)cfg;
328
+ config_file_backend *h = GIT_CONTAINER_OF(cfg, config_file_backend, parent);
305
329
  git_config_entries *entries = NULL;
306
330
  git_config_entry *entry;
307
331
  int error = 0;
308
332
 
309
- if (!h->parent.readonly && ((error = config_refresh(cfg)) < 0))
333
+ if (!h->parent.readonly && ((error = config_file_refresh(cfg)) < 0))
310
334
  return error;
311
335
 
312
- if ((entries = diskfile_entries_take(h)) == NULL)
313
- return -1;
336
+ if ((error = config_file_entries_take(&entries, h)) < 0)
337
+ return error;
314
338
 
315
339
  if ((error = (git_config_entries_get(&entry, entries, key))) < 0) {
316
340
  git_config_entries_free(entries);
317
341
  return error;
318
342
  }
319
343
 
320
- entry->free = free_diskfile_entry;
344
+ entry->free = config_file_entry_free;
321
345
  entry->payload = entries;
322
346
  *out = entry;
323
347
 
324
348
  return 0;
325
349
  }
326
350
 
327
- static int config_set_multivar(
351
+ static int config_file_set_multivar(
328
352
  git_config_backend *cfg, const char *name, const char *regexp, const char *value)
329
353
  {
330
- diskfile_backend *b = (diskfile_backend *)cfg;
331
- char *key;
332
- regex_t preg;
354
+ config_file_backend *b = GIT_CONTAINER_OF(cfg, config_file_backend, parent);
355
+ git_regexp preg;
333
356
  int result;
357
+ char *key;
334
358
 
335
359
  assert(regexp);
336
360
 
337
361
  if ((result = git_config__normalize_name(name, &key)) < 0)
338
362
  return result;
339
363
 
340
- result = p_regcomp(&preg, regexp, REG_EXTENDED);
341
- if (result != 0) {
342
- git_error_set_regex(&preg, result);
343
- result = -1;
364
+ if ((result = git_regexp_compile(&preg, regexp, 0)) < 0)
344
365
  goto out;
345
- }
346
366
 
347
- /* If we do have it, set call config_write() and reload */
348
- 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)
349
369
  goto out;
350
370
 
351
- result = config_refresh(cfg);
352
-
353
371
  out:
354
372
  git__free(key);
355
- regfree(&preg);
373
+ git_regexp_dispose(&preg);
356
374
 
357
375
  return result;
358
376
  }
359
377
 
360
- static int config_delete(git_config_backend *cfg, const char *name)
378
+ static int config_file_delete(git_config_backend *cfg, const char *name)
361
379
  {
362
- diskfile_backend *b = (diskfile_backend *)cfg;
380
+ config_file_backend *b = GIT_CONTAINER_OF(cfg, config_file_backend, parent);
363
381
  git_config_entries *entries = NULL;
364
382
  git_config_entry *entry;
365
383
  char *key = NULL;
@@ -368,7 +386,7 @@ static int config_delete(git_config_backend *cfg, const char *name)
368
386
  if ((error = git_config__normalize_name(name, &key)) < 0)
369
387
  goto out;
370
388
 
371
- if ((entries = diskfile_entries_take(&b->header)) == NULL)
389
+ if ((error = config_file_entries_take(&entries, b)) < 0)
372
390
  goto out;
373
391
 
374
392
  /* Check whether we'd be modifying an included or multivar key */
@@ -378,10 +396,7 @@ static int config_delete(git_config_backend *cfg, const char *name)
378
396
  goto out;
379
397
  }
380
398
 
381
- if ((error = config_write(b, name, entry->name, NULL, NULL)) < 0)
382
- goto out;
383
-
384
- if ((error = config_refresh(cfg)) < 0)
399
+ if ((error = config_file_write(b, name, entry->name, NULL, NULL)) < 0)
385
400
  goto out;
386
401
 
387
402
  out:
@@ -390,22 +405,20 @@ out:
390
405
  return error;
391
406
  }
392
407
 
393
- 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)
394
409
  {
395
- diskfile_backend *b = (diskfile_backend *)cfg;
410
+ config_file_backend *b = GIT_CONTAINER_OF(cfg, config_file_backend, parent);
396
411
  git_config_entries *entries = NULL;
397
412
  git_config_entry *entry = NULL;
398
- regex_t preg = { 0 };
413
+ git_regexp preg = GIT_REGEX_INIT;
399
414
  char *key = NULL;
400
415
  int result;
401
416
 
402
417
  if ((result = git_config__normalize_name(name, &key)) < 0)
403
418
  goto out;
404
419
 
405
- if ((entries = diskfile_entries_take(&b->header)) == NULL) {
406
- result = -1;
420
+ if ((result = config_file_entries_take(&entries, b)) < 0)
407
421
  goto out;
408
- }
409
422
 
410
423
  if ((result = git_config_entries_get(&entry, entries, key)) < 0) {
411
424
  if (result == GIT_ENOTFOUND)
@@ -413,28 +426,22 @@ static int config_delete_multivar(git_config_backend *cfg, const char *name, con
413
426
  goto out;
414
427
  }
415
428
 
416
- if ((result = p_regcomp(&preg, regexp, REG_EXTENDED)) != 0) {
417
- git_error_set_regex(&preg, result);
418
- result = -1;
419
- goto out;
420
- }
421
-
422
- if ((result = config_write(b, name, key, &preg, NULL)) < 0)
429
+ if ((result = git_regexp_compile(&preg, regexp, 0)) < 0)
423
430
  goto out;
424
431
 
425
- if ((result = config_refresh(cfg)) < 0)
432
+ if ((result = config_file_write(b, name, key, &preg, NULL)) < 0)
426
433
  goto out;
427
434
 
428
435
  out:
429
436
  git_config_entries_free(entries);
430
437
  git__free(key);
431
- regfree(&preg);
438
+ git_regexp_dispose(&preg);
432
439
  return result;
433
440
  }
434
441
 
435
- static int config_lock(git_config_backend *_cfg)
442
+ static int config_file_lock(git_config_backend *_cfg)
436
443
  {
437
- diskfile_backend *cfg = (diskfile_backend *) _cfg;
444
+ config_file_backend *cfg = GIT_CONTAINER_OF(_cfg, config_file_backend, parent);
438
445
  int error;
439
446
 
440
447
  if ((error = git_filebuf_open(&cfg->locked_buf, cfg->file.path, 0, GIT_CONFIG_FILE_MODE)) < 0)
@@ -451,9 +458,9 @@ static int config_lock(git_config_backend *_cfg)
451
458
 
452
459
  }
453
460
 
454
- static int config_unlock(git_config_backend *_cfg, int success)
461
+ static int config_file_unlock(git_config_backend *_cfg, int success)
455
462
  {
456
- diskfile_backend *cfg = (diskfile_backend *) _cfg;
463
+ config_file_backend *cfg = GIT_CONTAINER_OF(_cfg, config_file_backend, parent);
457
464
  int error = 0;
458
465
 
459
466
  if (success) {
@@ -470,145 +477,29 @@ static int config_unlock(git_config_backend *_cfg, int success)
470
477
 
471
478
  int git_config_backend_from_file(git_config_backend **out, const char *path)
472
479
  {
473
- diskfile_backend *backend;
480
+ config_file_backend *backend;
474
481
 
475
- backend = git__calloc(1, sizeof(diskfile_backend));
482
+ backend = git__calloc(1, sizeof(config_file_backend));
476
483
  GIT_ERROR_CHECK_ALLOC(backend);
477
484
 
478
- backend->header.parent.version = GIT_CONFIG_BACKEND_VERSION;
479
- git_mutex_init(&backend->header.values_mutex);
485
+ backend->parent.version = GIT_CONFIG_BACKEND_VERSION;
486
+ git_mutex_init(&backend->values_mutex);
480
487
 
481
488
  backend->file.path = git__strdup(path);
482
489
  GIT_ERROR_CHECK_ALLOC(backend->file.path);
483
490
  git_array_init(backend->file.includes);
484
491
 
485
- backend->header.parent.open = config_open;
486
- backend->header.parent.get = config_get;
487
- backend->header.parent.set = config_set;
488
- backend->header.parent.set_multivar = config_set_multivar;
489
- backend->header.parent.del = config_delete;
490
- backend->header.parent.del_multivar = config_delete_multivar;
491
- backend->header.parent.iterator = config_iterator_new;
492
- backend->header.parent.snapshot = config_snapshot;
493
- backend->header.parent.lock = config_lock;
494
- backend->header.parent.unlock = config_unlock;
495
- backend->header.parent.free = backend_free;
496
-
497
- *out = (git_config_backend *)backend;
498
-
499
- return 0;
500
- }
501
-
502
- static int config_set_readonly(git_config_backend *cfg, const char *name, const char *value)
503
- {
504
- GIT_UNUSED(cfg);
505
- GIT_UNUSED(name);
506
- GIT_UNUSED(value);
507
-
508
- return config_error_readonly();
509
- }
510
-
511
- static int config_set_multivar_readonly(
512
- git_config_backend *cfg, const char *name, const char *regexp, const char *value)
513
- {
514
- GIT_UNUSED(cfg);
515
- GIT_UNUSED(name);
516
- GIT_UNUSED(regexp);
517
- GIT_UNUSED(value);
518
-
519
- return config_error_readonly();
520
- }
521
-
522
- static int config_delete_multivar_readonly(git_config_backend *cfg, const char *name, const char *regexp)
523
- {
524
- GIT_UNUSED(cfg);
525
- GIT_UNUSED(name);
526
- GIT_UNUSED(regexp);
527
-
528
- return config_error_readonly();
529
- }
530
-
531
- static int config_delete_readonly(git_config_backend *cfg, const char *name)
532
- {
533
- GIT_UNUSED(cfg);
534
- GIT_UNUSED(name);
535
-
536
- return config_error_readonly();
537
- }
538
-
539
- static int config_lock_readonly(git_config_backend *_cfg)
540
- {
541
- GIT_UNUSED(_cfg);
542
-
543
- return config_error_readonly();
544
- }
545
-
546
- static int config_unlock_readonly(git_config_backend *_cfg, int success)
547
- {
548
- GIT_UNUSED(_cfg);
549
- GIT_UNUSED(success);
550
-
551
- return config_error_readonly();
552
- }
553
-
554
- static void backend_readonly_free(git_config_backend *_backend)
555
- {
556
- diskfile_backend *backend = (diskfile_backend *)_backend;
557
-
558
- if (backend == NULL)
559
- return;
560
-
561
- git_config_entries_free(backend->header.entries);
562
- git_mutex_free(&backend->header.values_mutex);
563
- git__free(backend);
564
- }
565
-
566
- static int config_readonly_open(git_config_backend *cfg, git_config_level_t level, const git_repository *repo)
567
- {
568
- diskfile_readonly_backend *b = (diskfile_readonly_backend *) cfg;
569
- diskfile_backend *src = b->snapshot_from;
570
- diskfile_header *src_header = &src->header;
571
- git_config_entries *entries;
572
- int error;
573
-
574
- if (!src_header->parent.readonly && (error = config_refresh(&src_header->parent)) < 0)
575
- return error;
576
-
577
- /* We're just copying data, don't care about the level or repo*/
578
- GIT_UNUSED(level);
579
- GIT_UNUSED(repo);
580
-
581
- if ((entries = diskfile_entries_take(src_header)) == NULL)
582
- return -1;
583
- b->header.entries = entries;
584
-
585
- return 0;
586
- }
587
-
588
- static int config_snapshot(git_config_backend **out, git_config_backend *in)
589
- {
590
- diskfile_readonly_backend *backend;
591
-
592
- backend = git__calloc(1, sizeof(diskfile_readonly_backend));
593
- GIT_ERROR_CHECK_ALLOC(backend);
594
-
595
- backend->header.parent.version = GIT_CONFIG_BACKEND_VERSION;
596
- git_mutex_init(&backend->header.values_mutex);
597
-
598
- backend->snapshot_from = (diskfile_backend *) in;
599
-
600
- backend->header.parent.readonly = 1;
601
- backend->header.parent.version = GIT_CONFIG_BACKEND_VERSION;
602
- backend->header.parent.open = config_readonly_open;
603
- backend->header.parent.get = config_get;
604
- backend->header.parent.set = config_set_readonly;
605
- backend->header.parent.set_multivar = config_set_multivar_readonly;
606
- backend->header.parent.del = config_delete_readonly;
607
- backend->header.parent.del_multivar = config_delete_multivar_readonly;
608
- backend->header.parent.iterator = config_iterator_new;
609
- backend->header.parent.lock = config_lock_readonly;
610
- backend->header.parent.unlock = config_unlock_readonly;
611
- 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;
612
503
 
613
504
  *out = (git_config_backend *)backend;
614
505
 
@@ -656,10 +547,9 @@ static char *escape_value(const char *ptr)
656
547
  return git_buf_detach(&buf);
657
548
  }
658
549
 
659
- static int parse_include(git_config_parser *reader,
660
- diskfile_parse_state *parse_data, const char *file)
550
+ static int parse_include(config_file_parse_data *parse_data, const char *file)
661
551
  {
662
- struct config_file *include;
552
+ config_file *include;
663
553
  git_buf path = GIT_BUF_INIT;
664
554
  char *dir;
665
555
  int result;
@@ -667,7 +557,7 @@ static int parse_include(git_config_parser *reader,
667
557
  if (!file)
668
558
  return 0;
669
559
 
670
- if ((result = git_path_dirname_r(&path, reader->file->path)) < 0)
560
+ if ((result = git_path_dirname_r(&path, parse_data->file->path)) < 0)
671
561
  return result;
672
562
 
673
563
  dir = git_buf_detach(&path);
@@ -677,14 +567,14 @@ static int parse_include(git_config_parser *reader,
677
567
  if (result < 0)
678
568
  return result;
679
569
 
680
- include = git_array_alloc(reader->file->includes);
570
+ include = git_array_alloc(parse_data->file->includes);
681
571
  GIT_ERROR_CHECK_ALLOC(include);
682
572
  memset(include, 0, sizeof(*include));
683
573
  git_array_init(include->includes);
684
574
  include->path = git_buf_detach(&path);
685
575
 
686
- result = config_read(parse_data->entries, parse_data->repo,
687
- 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);
688
578
 
689
579
  if (result == GIT_ENOTFOUND) {
690
580
  git_error_clear();
@@ -698,41 +588,41 @@ static int do_match_gitdir(
698
588
  int *matches,
699
589
  const git_repository *repo,
700
590
  const char *cfg_file,
701
- const char *value,
591
+ const char *condition,
702
592
  bool case_insensitive)
703
593
  {
704
- git_buf path = GIT_BUF_INIT;
705
- int error, fnmatch_flags;
706
-
707
- if (value[0] == '.' && git_path_is_dirsep(value[1])) {
708
- git_path_dirname_r(&path, cfg_file);
709
- git_buf_joinpath(&path, path.ptr, value + 2);
710
- } else if (value[0] == '~' && git_path_is_dirsep(value[1]))
711
- git_sysdir_expand_global_file(&path, value + 1);
712
- else if (!git_path_is_absolute(value))
713
- 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);
714
604
  else
715
- git_buf_sets(&path, value);
605
+ git_buf_sets(&pattern, condition);
716
606
 
717
- 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)) {
718
611
  error = -1;
719
612
  goto out;
720
613
  }
721
614
 
722
- if (git_path_is_dirsep(value[strlen(value) - 1]))
723
- git_buf_puts(&path, "**");
724
-
725
- fnmatch_flags = FNM_PATHNAME|FNM_LEADING_DIR;
726
- if (case_insensitive)
727
- fnmatch_flags |= FNM_IGNORECASE;
728
-
729
- 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)
730
616
  goto out;
731
617
 
732
- *matches = (error == 0);
618
+ if (git_path_is_dirsep(gitdir.ptr[gitdir.size - 1]))
619
+ git_buf_truncate(&gitdir, gitdir.size - 1);
733
620
 
621
+ *matches = wildmatch(pattern.ptr, gitdir.ptr,
622
+ WM_PATHNAME | (case_insensitive ? WM_CASEFOLD : 0)) == WM_MATCH;
734
623
  out:
735
- git_buf_dispose(&path);
624
+ git_buf_dispose(&pattern);
625
+ git_buf_dispose(&gitdir);
736
626
  return error;
737
627
  }
738
628
 
@@ -754,16 +644,67 @@ static int conditional_match_gitdir_i(
754
644
  return do_match_gitdir(matches, repo, cfg_file, value, true);
755
645
  }
756
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
+
757
698
  static const struct {
758
699
  const char *prefix;
759
700
  int (*matches)(int *matches, const git_repository *repo, const char *cfg, const char *value);
760
701
  } conditions[] = {
761
702
  { "gitdir:", conditional_match_gitdir },
762
- { "gitdir/i:", conditional_match_gitdir_i }
703
+ { "gitdir/i:", conditional_match_gitdir_i },
704
+ { "onbranch:", conditional_match_onbranch }
763
705
  };
764
706
 
765
- static int parse_conditional_include(git_config_parser *reader,
766
- 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)
767
708
  {
768
709
  char *condition;
769
710
  size_t i;
@@ -781,12 +722,12 @@ static int parse_conditional_include(git_config_parser *reader,
781
722
 
782
723
  if ((error = conditions[i].matches(&matches,
783
724
  parse_data->repo,
784
- parse_data->file_path,
725
+ parse_data->file->path,
785
726
  condition + strlen(conditions[i].prefix))) < 0)
786
727
  break;
787
728
 
788
729
  if (matches)
789
- error = parse_include(reader, parse_data, file);
730
+ error = parse_include(parse_data, file);
790
731
 
791
732
  break;
792
733
  }
@@ -804,12 +745,13 @@ static int read_on_variable(
804
745
  size_t line_len,
805
746
  void *data)
806
747
  {
807
- diskfile_parse_state *parse_data = (diskfile_parse_state *)data;
748
+ config_file_parse_data *parse_data = (config_file_parse_data *)data;
808
749
  git_buf buf = GIT_BUF_INIT;
809
750
  git_config_entry *entry;
810
751
  const char *c;
811
752
  int result = 0;
812
753
 
754
+ GIT_UNUSED(reader);
813
755
  GIT_UNUSED(line);
814
756
  GIT_UNUSED(line_len);
815
757
 
@@ -842,25 +784,25 @@ static int read_on_variable(
842
784
 
843
785
  /* Add or append the new config option */
844
786
  if (!git__strcmp(entry->name, "include.path"))
845
- result = parse_include(reader, parse_data, entry->value);
787
+ result = parse_include(parse_data, entry->value);
846
788
  else if (!git__prefixcmp(entry->name, "includeif.") &&
847
789
  !git__suffixcmp(entry->name, ".path"))
848
- result = parse_conditional_include(reader, parse_data,
849
- entry->name, entry->value);
790
+ result = parse_conditional_include(parse_data, entry->name, entry->value);
850
791
 
851
792
  return result;
852
793
  }
853
794
 
854
- static int config_read(
795
+ static int config_file_read_buffer(
855
796
  git_config_entries *entries,
856
797
  const git_repository *repo,
857
- git_config_file *file,
798
+ config_file *file,
858
799
  git_config_level_t level,
859
- int depth)
800
+ int depth,
801
+ const char *buf,
802
+ size_t buflen)
860
803
  {
861
- diskfile_parse_state parse_data;
804
+ config_file_parse_data parse_data;
862
805
  git_config_parser reader;
863
- git_buf contents = GIT_BUF_INIT;
864
806
  int error;
865
807
 
866
808
  if (depth >= MAX_INCLUDE_DEPTH) {
@@ -868,30 +810,55 @@ static int config_read(
868
810
  return -1;
869
811
  }
870
812
 
871
- if ((error = git_futils_readbuffer(&contents, file->path)) < 0)
872
- goto out;
873
-
874
- git_parse_ctx_init(&reader.ctx, contents.ptr, contents.size);
875
-
876
- if ((error = git_hash_buf(&file->checksum, contents.ptr, contents.size)) < 0)
877
- goto out;
878
-
879
813
  /* Initialize the reading position */
880
- reader.file = file;
881
- git_parse_ctx_init(&reader.ctx, contents.ptr, contents.size);
814
+ reader.path = file->path;
815
+ git_parse_ctx_init(&reader.ctx, buf, buflen);
882
816
 
883
817
  /* If the file is empty, there's nothing for us to do */
884
- if (!reader.ctx.content || *reader.ctx.content == '\0')
818
+ if (!reader.ctx.content || *reader.ctx.content == '\0') {
819
+ error = 0;
885
820
  goto out;
821
+ }
886
822
 
887
823
  parse_data.repo = repo;
888
- parse_data.file_path = file->path;
824
+ parse_data.file = file;
889
825
  parse_data.entries = entries;
890
826
  parse_data.level = level;
891
827
  parse_data.depth = depth;
892
828
 
893
829
  error = git_config_parse(&reader, NULL, read_on_variable, NULL, NULL, &parse_data);
894
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
+
895
862
  out:
896
863
  git_buf_dispose(&contents);
897
864
  return error;
@@ -954,7 +921,7 @@ struct write_data {
954
921
  const char *section;
955
922
  const char *orig_name;
956
923
  const char *name;
957
- const regex_t *preg;
924
+ const git_regexp *preg;
958
925
  const char *value;
959
926
  };
960
927
 
@@ -1059,7 +1026,7 @@ static int write_on_variable(
1059
1026
 
1060
1027
  /* If we have a regex to match the value, see if it matches */
1061
1028
  if (has_matched && write_data->preg != NULL)
1062
- has_matched = (regexec(write_data->preg, var_value, 0, NULL, 0) == 0);
1029
+ has_matched = (git_regexp_match(write_data->preg, var_value) == 0);
1063
1030
 
1064
1031
  /* If this isn't the name/value we're looking for, simply dump the
1065
1032
  * existing data back out and continue on.
@@ -1120,39 +1087,33 @@ static int write_on_eof(
1120
1087
  /*
1121
1088
  * This is pretty much the parsing, except we write out anything we don't have
1122
1089
  */
1123
- 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
+
1124
1092
  {
1125
- int result;
1126
- char *orig_section, *section, *orig_name, *name, *ldot;
1127
- git_filebuf file = GIT_FILEBUF_INIT;
1093
+ char *orig_section = NULL, *section = NULL, *orig_name, *name, *ldot;
1128
1094
  git_buf buf = GIT_BUF_INIT, contents = GIT_BUF_INIT;
1129
- git_config_parser reader;
1095
+ git_config_parser parser = GIT_CONFIG_PARSER_INIT;
1096
+ git_filebuf file = GIT_FILEBUF_INIT;
1130
1097
  struct write_data write_data;
1098
+ int error;
1131
1099
 
1132
- memset(&reader, 0, sizeof(reader));
1133
- reader.file = &cfg->file;
1100
+ memset(&write_data, 0, sizeof(write_data));
1134
1101
 
1135
1102
  if (cfg->locked) {
1136
- result = git_buf_puts(&contents, git_buf_cstr(&cfg->locked_content) == NULL ? "" : 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));
1137
1104
  } else {
1138
- /* Lock the file */
1139
- if ((result = git_filebuf_open(
1140
- &file, cfg->file.path, GIT_FILEBUF_HASH_CONTENTS, GIT_CONFIG_FILE_MODE)) < 0) {
1141
- git_buf_dispose(&contents);
1142
- return result;
1143
- }
1105
+ if ((error = git_filebuf_open(&file, cfg->file.path, GIT_FILEBUF_HASH_CONTENTS,
1106
+ GIT_CONFIG_FILE_MODE)) < 0)
1107
+ goto done;
1144
1108
 
1145
1109
  /* We need to read in our own config file */
1146
- result = git_futils_readbuffer(&contents, cfg->file.path);
1110
+ error = git_futils_readbuffer(&contents, cfg->file.path);
1147
1111
  }
1112
+ if (error < 0 && error != GIT_ENOTFOUND)
1113
+ goto done;
1148
1114
 
1149
- /* Initialise the reading position */
1150
- if (result == 0 || result == GIT_ENOTFOUND) {
1151
- git_parse_ctx_init(&reader.ctx, contents.ptr, contents.size);
1152
- } else {
1153
- git_filebuf_cleanup(&file);
1154
- return -1; /* OS error when reading the file */
1155
- }
1115
+ if ((git_config_parser_init(&parser, cfg->file.path, contents.ptr, contents.size)) < 0)
1116
+ goto done;
1156
1117
 
1157
1118
  ldot = strrchr(key, '.');
1158
1119
  name = ldot + 1;
@@ -1165,30 +1126,16 @@ static int config_write(diskfile_backend *cfg, const char *orig_key, const char
1165
1126
  GIT_ERROR_CHECK_ALLOC(orig_section);
1166
1127
 
1167
1128
  write_data.buf = &buf;
1168
- git_buf_init(&write_data.buffered_comment, 0);
1169
1129
  write_data.orig_section = orig_section;
1170
1130
  write_data.section = section;
1171
- write_data.in_section = 0;
1172
- write_data.preg_replaced = 0;
1173
1131
  write_data.orig_name = orig_name;
1174
1132
  write_data.name = name;
1175
1133
  write_data.preg = preg;
1176
1134
  write_data.value = value;
1177
1135
 
1178
- result = git_config_parse(&reader,
1179
- write_on_section,
1180
- write_on_variable,
1181
- write_on_comment,
1182
- write_on_eof,
1183
- &write_data);
1184
- git__free(section);
1185
- git__free(orig_section);
1186
- git_buf_dispose(&write_data.buffered_comment);
1187
-
1188
- if (result < 0) {
1189
- 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)
1190
1138
  goto done;
1191
- }
1192
1139
 
1193
1140
  if (cfg->locked) {
1194
1141
  size_t len = buf.asize;
@@ -1197,12 +1144,22 @@ static int config_write(diskfile_backend *cfg, const char *orig_key, const char
1197
1144
  git_buf_attach(&cfg->locked_content, git_buf_detach(&buf), len);
1198
1145
  } else {
1199
1146
  git_filebuf_write(&file, git_buf_cstr(&buf), git_buf_len(&buf));
1200
- 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;
1201
1153
  }
1202
1154
 
1203
1155
  done:
1156
+ git__free(section);
1157
+ git__free(orig_section);
1158
+ git_buf_dispose(&write_data.buffered_comment);
1204
1159
  git_buf_dispose(&buf);
1205
1160
  git_buf_dispose(&contents);
1206
- git_parse_ctx_clear(&reader.ctx);
1207
- return result;
1161
+ git_filebuf_cleanup(&file);
1162
+ git_config_parser_dispose(&parser);
1163
+
1164
+ return error;
1208
1165
  }