rugged 0.27.10 → 0.27.10.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (420) hide show
  1. checksums.yaml +4 -4
  2. data/lib/rugged/version.rb +1 -1
  3. data/vendor/libgit2/AUTHORS +0 -1
  4. data/vendor/libgit2/CMakeLists.txt +54 -98
  5. data/vendor/libgit2/COPYING +0 -28
  6. data/vendor/libgit2/cmake/Modules/AddCFlagIfSupported.cmake +1 -15
  7. data/vendor/libgit2/cmake/Modules/EnableWarnings.cmake +8 -9
  8. data/vendor/libgit2/cmake/Modules/FindCoreFoundation.cmake +2 -2
  9. data/vendor/libgit2/cmake/Modules/FindGSSAPI.cmake +1 -1
  10. data/vendor/libgit2/cmake/Modules/FindSecurity.cmake +2 -2
  11. data/vendor/libgit2/cmake/Modules/FindStatNsec.cmake +0 -6
  12. data/vendor/libgit2/deps/http-parser/CMakeLists.txt +0 -2
  13. data/vendor/libgit2/deps/http-parser/{COPYING → LICENSE-MIT} +0 -0
  14. data/vendor/libgit2/deps/http-parser/http_parser.c +6 -11
  15. data/vendor/libgit2/deps/regex/CMakeLists.txt +2 -0
  16. data/vendor/libgit2/deps/regex/config.h +7 -0
  17. data/vendor/libgit2/deps/regex/regcomp.c +3857 -0
  18. data/vendor/libgit2/deps/regex/regex.c +92 -0
  19. data/vendor/libgit2/deps/regex/regex.h +582 -0
  20. data/vendor/libgit2/deps/regex/regex_internal.c +1744 -0
  21. data/vendor/libgit2/deps/regex/regex_internal.h +819 -0
  22. data/vendor/libgit2/deps/regex/regexec.c +4369 -0
  23. data/vendor/libgit2/deps/zlib/CMakeLists.txt +0 -1
  24. data/vendor/libgit2/deps/zlib/adler32.c +7 -0
  25. data/vendor/libgit2/deps/zlib/crc32.c +7 -0
  26. data/vendor/libgit2/include/git2.h +0 -5
  27. data/vendor/libgit2/include/git2/annotated_commit.h +0 -9
  28. data/vendor/libgit2/include/git2/attr.h +20 -38
  29. data/vendor/libgit2/include/git2/blame.h +25 -42
  30. data/vendor/libgit2/include/git2/blob.h +13 -45
  31. data/vendor/libgit2/include/git2/branch.h +1 -1
  32. data/vendor/libgit2/include/git2/buffer.h +16 -22
  33. data/vendor/libgit2/include/git2/checkout.h +32 -65
  34. data/vendor/libgit2/include/git2/cherrypick.h +7 -9
  35. data/vendor/libgit2/include/git2/clone.h +10 -12
  36. data/vendor/libgit2/include/git2/commit.h +3 -53
  37. data/vendor/libgit2/include/git2/common.h +8 -60
  38. data/vendor/libgit2/include/git2/config.h +19 -30
  39. data/vendor/libgit2/include/git2/describe.h +9 -32
  40. data/vendor/libgit2/include/git2/diff.h +156 -208
  41. data/vendor/libgit2/include/git2/errors.h +46 -54
  42. data/vendor/libgit2/include/git2/filter.h +0 -8
  43. data/vendor/libgit2/include/git2/ignore.h +2 -2
  44. data/vendor/libgit2/include/git2/index.h +52 -74
  45. data/vendor/libgit2/include/git2/indexer.h +6 -76
  46. data/vendor/libgit2/include/git2/inttypes.h +309 -0
  47. data/vendor/libgit2/include/git2/merge.h +18 -35
  48. data/vendor/libgit2/include/git2/net.h +5 -0
  49. data/vendor/libgit2/include/git2/notes.h +1 -1
  50. data/vendor/libgit2/include/git2/object.h +29 -17
  51. data/vendor/libgit2/include/git2/odb.h +11 -12
  52. data/vendor/libgit2/include/git2/odb_backend.h +9 -10
  53. data/vendor/libgit2/include/git2/oid.h +2 -2
  54. data/vendor/libgit2/include/git2/pack.h +3 -14
  55. data/vendor/libgit2/include/git2/proxy.h +8 -14
  56. data/vendor/libgit2/include/git2/rebase.h +6 -53
  57. data/vendor/libgit2/include/git2/refs.h +15 -33
  58. data/vendor/libgit2/include/git2/refspec.h +0 -17
  59. data/vendor/libgit2/include/git2/remote.h +24 -123
  60. data/vendor/libgit2/include/git2/repository.h +39 -76
  61. data/vendor/libgit2/include/git2/revert.h +4 -6
  62. data/vendor/libgit2/include/git2/revwalk.h +7 -7
  63. data/vendor/libgit2/include/git2/signature.h +2 -2
  64. data/vendor/libgit2/include/git2/stash.h +12 -15
  65. data/vendor/libgit2/include/git2/status.h +20 -33
  66. data/vendor/libgit2/include/git2/submodule.h +12 -30
  67. data/vendor/libgit2/include/git2/sys/commit.h +1 -1
  68. data/vendor/libgit2/include/git2/sys/config.h +13 -13
  69. data/vendor/libgit2/include/git2/sys/filter.h +6 -6
  70. data/vendor/libgit2/include/git2/sys/index.h +0 -3
  71. data/vendor/libgit2/include/git2/sys/mempack.h +35 -35
  72. data/vendor/libgit2/include/git2/sys/merge.h +4 -9
  73. data/vendor/libgit2/include/git2/sys/odb_backend.h +22 -66
  74. data/vendor/libgit2/include/git2/sys/refdb_backend.h +40 -76
  75. data/vendor/libgit2/include/git2/sys/repository.h +1 -5
  76. data/vendor/libgit2/include/git2/sys/stream.h +12 -92
  77. data/vendor/libgit2/include/git2/sys/time.h +31 -0
  78. data/vendor/libgit2/include/git2/sys/transport.h +83 -129
  79. data/vendor/libgit2/include/git2/tag.h +4 -13
  80. data/vendor/libgit2/include/git2/trace.h +2 -2
  81. data/vendor/libgit2/include/git2/transaction.h +0 -1
  82. data/vendor/libgit2/include/git2/transport.h +311 -11
  83. data/vendor/libgit2/include/git2/tree.h +4 -4
  84. data/vendor/libgit2/include/git2/types.h +111 -33
  85. data/vendor/libgit2/include/git2/version.h +4 -4
  86. data/vendor/libgit2/include/git2/worktree.h +13 -48
  87. data/vendor/libgit2/libgit2.pc.in +13 -0
  88. data/vendor/libgit2/src/CMakeLists.txt +164 -96
  89. data/vendor/libgit2/src/annotated_commit.c +8 -15
  90. data/vendor/libgit2/src/apply.c +31 -537
  91. data/vendor/libgit2/src/apply.h +1 -3
  92. data/vendor/libgit2/src/array.h +2 -2
  93. data/vendor/libgit2/src/attr.c +75 -81
  94. data/vendor/libgit2/src/attr_file.c +121 -207
  95. data/vendor/libgit2/src/attr_file.h +9 -9
  96. data/vendor/libgit2/src/attrcache.c +53 -51
  97. data/vendor/libgit2/src/attrcache.h +1 -2
  98. data/vendor/libgit2/src/blame.c +20 -47
  99. data/vendor/libgit2/src/blame.h +1 -2
  100. data/vendor/libgit2/src/blame_git.c +20 -37
  101. data/vendor/libgit2/src/blob.c +42 -128
  102. data/vendor/libgit2/src/blob.h +2 -19
  103. data/vendor/libgit2/src/branch.c +43 -67
  104. data/vendor/libgit2/src/buf_text.c +6 -7
  105. data/vendor/libgit2/src/buffer.c +57 -69
  106. data/vendor/libgit2/src/buffer.h +1 -1
  107. data/vendor/libgit2/src/cache.c +45 -38
  108. data/vendor/libgit2/src/cache.h +3 -3
  109. data/vendor/libgit2/src/cc-compat.h +3 -20
  110. data/vendor/libgit2/src/checkout.c +90 -109
  111. data/vendor/libgit2/src/cherrypick.c +9 -15
  112. data/vendor/libgit2/src/clone.c +27 -49
  113. data/vendor/libgit2/src/clone.h +0 -4
  114. data/vendor/libgit2/src/commit.c +49 -117
  115. data/vendor/libgit2/src/commit.h +0 -7
  116. data/vendor/libgit2/src/commit_list.c +78 -30
  117. data/vendor/libgit2/src/commit_list.h +2 -2
  118. data/vendor/libgit2/src/common.h +91 -27
  119. data/vendor/libgit2/src/config.c +176 -194
  120. data/vendor/libgit2/src/config.h +20 -8
  121. data/vendor/libgit2/src/config_cache.c +35 -41
  122. data/vendor/libgit2/src/config_file.c +753 -439
  123. data/vendor/libgit2/src/config_file.h +73 -0
  124. data/vendor/libgit2/src/config_parse.c +63 -114
  125. data/vendor/libgit2/src/config_parse.h +16 -17
  126. data/vendor/libgit2/src/crlf.c +190 -219
  127. data/vendor/libgit2/src/delta.c +18 -25
  128. data/vendor/libgit2/src/describe.c +41 -42
  129. data/vendor/libgit2/src/diff.c +68 -53
  130. data/vendor/libgit2/src/diff.h +1 -2
  131. data/vendor/libgit2/src/diff_driver.c +49 -47
  132. data/vendor/libgit2/src/diff_file.c +17 -19
  133. data/vendor/libgit2/src/diff_file.h +1 -1
  134. data/vendor/libgit2/src/diff_generate.c +106 -162
  135. data/vendor/libgit2/src/diff_generate.h +3 -3
  136. data/vendor/libgit2/src/diff_parse.c +4 -4
  137. data/vendor/libgit2/src/diff_print.c +30 -42
  138. data/vendor/libgit2/src/diff_stats.c +7 -22
  139. data/vendor/libgit2/src/diff_tform.c +16 -16
  140. data/vendor/libgit2/src/diff_xdiff.c +3 -15
  141. data/vendor/libgit2/src/errors.c +39 -51
  142. data/vendor/libgit2/src/features.h.in +3 -11
  143. data/vendor/libgit2/src/fetch.c +5 -10
  144. data/vendor/libgit2/src/fetchhead.c +17 -17
  145. data/vendor/libgit2/src/filebuf.c +36 -32
  146. data/vendor/libgit2/src/filebuf.h +2 -2
  147. data/vendor/libgit2/src/{futils.c → fileops.c} +73 -80
  148. data/vendor/libgit2/src/{futils.h → fileops.h} +6 -6
  149. data/vendor/libgit2/src/filter.c +38 -46
  150. data/vendor/libgit2/src/filter.h +10 -0
  151. data/vendor/libgit2/src/fnmatch.c +248 -0
  152. data/vendor/libgit2/src/fnmatch.h +48 -0
  153. data/vendor/libgit2/src/global.c +63 -48
  154. data/vendor/libgit2/src/global.h +2 -0
  155. data/vendor/libgit2/src/hash.c +0 -61
  156. data/vendor/libgit2/src/hash.h +19 -20
  157. data/vendor/libgit2/src/hash/hash_collisiondetect.h +47 -0
  158. data/vendor/libgit2/src/hash/{sha1/common_crypto.c → hash_common_crypto.h} +17 -17
  159. data/vendor/libgit2/src/hash/{sha1/generic.c → hash_generic.c} +10 -22
  160. data/vendor/libgit2/src/hash/{sha1/generic.h → hash_generic.h} +10 -4
  161. data/vendor/libgit2/src/hash/hash_openssl.h +59 -0
  162. data/vendor/libgit2/src/hash/{sha1/win32.c → hash_win32.c} +37 -47
  163. data/vendor/libgit2/src/hash/{sha1/win32.h → hash_win32.h} +19 -6
  164. data/vendor/libgit2/src/hash/{sha1/sha1dc → sha1dc}/sha1.c +3 -14
  165. data/vendor/libgit2/src/hash/{sha1/sha1dc → sha1dc}/sha1.h +0 -0
  166. data/vendor/libgit2/src/hash/{sha1/sha1dc → sha1dc}/ubc_check.c +0 -0
  167. data/vendor/libgit2/src/hash/{sha1/sha1dc → sha1dc}/ubc_check.h +0 -0
  168. data/vendor/libgit2/src/hashsig.c +5 -5
  169. data/vendor/libgit2/src/idxmap.c +61 -107
  170. data/vendor/libgit2/src/idxmap.h +31 -153
  171. data/vendor/libgit2/src/ignore.c +47 -43
  172. data/vendor/libgit2/src/index.c +232 -337
  173. data/vendor/libgit2/src/index.h +1 -17
  174. data/vendor/libgit2/src/indexer.c +175 -346
  175. data/vendor/libgit2/src/integer.h +26 -71
  176. data/vendor/libgit2/src/iterator.c +70 -142
  177. data/vendor/libgit2/src/iterator.h +0 -15
  178. data/vendor/libgit2/src/khash.h +1 -3
  179. data/vendor/libgit2/src/map.h +1 -1
  180. data/vendor/libgit2/src/merge.c +100 -144
  181. data/vendor/libgit2/src/merge_driver.c +11 -11
  182. data/vendor/libgit2/src/merge_file.c +2 -2
  183. data/vendor/libgit2/src/mwindow.c +29 -24
  184. data/vendor/libgit2/src/mwindow.h +4 -4
  185. data/vendor/libgit2/src/netops.c +156 -55
  186. data/vendor/libgit2/src/netops.h +23 -3
  187. data/vendor/libgit2/src/notes.c +11 -16
  188. data/vendor/libgit2/src/object.c +69 -120
  189. data/vendor/libgit2/src/object.h +9 -22
  190. data/vendor/libgit2/src/object_api.c +8 -8
  191. data/vendor/libgit2/src/odb.c +93 -116
  192. data/vendor/libgit2/src/odb.h +7 -8
  193. data/vendor/libgit2/src/odb_loose.c +55 -62
  194. data/vendor/libgit2/src/odb_mempack.c +34 -21
  195. data/vendor/libgit2/src/odb_pack.c +14 -18
  196. data/vendor/libgit2/src/offmap.c +35 -53
  197. data/vendor/libgit2/src/offmap.h +21 -108
  198. data/vendor/libgit2/src/oid.c +7 -12
  199. data/vendor/libgit2/src/oidmap.c +47 -49
  200. data/vendor/libgit2/src/oidmap.h +24 -101
  201. data/vendor/libgit2/src/pack-objects.c +87 -88
  202. data/vendor/libgit2/src/pack-objects.h +8 -2
  203. data/vendor/libgit2/src/pack.c +101 -99
  204. data/vendor/libgit2/src/pack.h +19 -17
  205. data/vendor/libgit2/src/parse.c +0 -10
  206. data/vendor/libgit2/src/parse.h +3 -3
  207. data/vendor/libgit2/src/patch.c +4 -4
  208. data/vendor/libgit2/src/patch_generate.c +20 -20
  209. data/vendor/libgit2/src/patch_parse.c +63 -151
  210. data/vendor/libgit2/src/path.c +104 -117
  211. data/vendor/libgit2/src/path.h +71 -3
  212. data/vendor/libgit2/src/pathspec.c +19 -19
  213. data/vendor/libgit2/src/pool.c +22 -26
  214. data/vendor/libgit2/src/pool.h +7 -7
  215. data/vendor/libgit2/src/posix.c +10 -10
  216. data/vendor/libgit2/src/posix.h +1 -12
  217. data/vendor/libgit2/src/proxy.c +3 -8
  218. data/vendor/libgit2/src/push.c +31 -37
  219. data/vendor/libgit2/src/push.h +1 -2
  220. data/vendor/libgit2/src/rebase.c +59 -115
  221. data/vendor/libgit2/src/refdb.c +3 -15
  222. data/vendor/libgit2/src/refdb_fs.c +254 -381
  223. data/vendor/libgit2/src/reflog.c +15 -13
  224. data/vendor/libgit2/src/refs.c +88 -118
  225. data/vendor/libgit2/src/refs.h +3 -5
  226. data/vendor/libgit2/src/refspec.c +37 -56
  227. data/vendor/libgit2/src/refspec.h +1 -1
  228. data/vendor/libgit2/src/remote.c +215 -266
  229. data/vendor/libgit2/src/remote.h +2 -11
  230. data/vendor/libgit2/src/repository.c +225 -280
  231. data/vendor/libgit2/src/repository.h +40 -52
  232. data/vendor/libgit2/src/reset.c +8 -8
  233. data/vendor/libgit2/src/revert.c +9 -14
  234. data/vendor/libgit2/src/revparse.c +48 -47
  235. data/vendor/libgit2/src/revwalk.c +57 -120
  236. data/vendor/libgit2/src/revwalk.h +1 -22
  237. data/vendor/libgit2/src/settings.c +10 -47
  238. data/vendor/libgit2/src/signature.c +11 -11
  239. data/vendor/libgit2/src/sortedcache.c +36 -22
  240. data/vendor/libgit2/src/sortedcache.h +1 -1
  241. data/vendor/libgit2/src/stash.c +99 -125
  242. data/vendor/libgit2/src/status.c +22 -28
  243. data/vendor/libgit2/src/stream.h +2 -17
  244. data/vendor/libgit2/src/streams/curl.c +385 -0
  245. data/vendor/libgit2/src/{allocators/stdalloc.h → streams/curl.h} +5 -5
  246. data/vendor/libgit2/src/streams/openssl.c +114 -224
  247. data/vendor/libgit2/src/streams/openssl.h +108 -4
  248. data/vendor/libgit2/src/streams/socket.c +30 -55
  249. data/vendor/libgit2/src/streams/stransport.c +32 -57
  250. data/vendor/libgit2/src/streams/stransport.h +0 -5
  251. data/vendor/libgit2/src/streams/tls.c +19 -50
  252. data/vendor/libgit2/src/streams/tls.h +4 -12
  253. data/vendor/libgit2/src/strmap.c +74 -47
  254. data/vendor/libgit2/src/strmap.h +33 -108
  255. data/vendor/libgit2/src/submodule.c +216 -272
  256. data/vendor/libgit2/src/submodule.h +1 -1
  257. data/vendor/libgit2/src/sysdir.c +19 -29
  258. data/vendor/libgit2/src/tag.c +28 -41
  259. data/vendor/libgit2/src/tag.h +1 -2
  260. data/vendor/libgit2/src/trace.c +2 -2
  261. data/vendor/libgit2/src/trace.h +3 -3
  262. data/vendor/libgit2/src/trailer.c +38 -52
  263. data/vendor/libgit2/src/transaction.c +29 -30
  264. data/vendor/libgit2/src/transport.c +5 -5
  265. data/vendor/libgit2/src/transports/auth.c +11 -15
  266. data/vendor/libgit2/src/transports/auth.h +3 -10
  267. data/vendor/libgit2/src/transports/auth_negotiate.c +18 -33
  268. data/vendor/libgit2/src/transports/auth_negotiate.h +2 -2
  269. data/vendor/libgit2/src/transports/cred.c +24 -24
  270. data/vendor/libgit2/src/{allocators/win32_crtdbg.h → transports/cred.h} +4 -5
  271. data/vendor/libgit2/src/transports/git.c +31 -26
  272. data/vendor/libgit2/src/transports/http.c +348 -881
  273. data/vendor/libgit2/src/transports/http.h +0 -2
  274. data/vendor/libgit2/src/transports/local.c +35 -35
  275. data/vendor/libgit2/src/transports/smart.c +47 -70
  276. data/vendor/libgit2/src/transports/smart.h +4 -3
  277. data/vendor/libgit2/src/transports/smart_pkt.c +40 -43
  278. data/vendor/libgit2/src/transports/smart_protocol.c +116 -96
  279. data/vendor/libgit2/src/transports/ssh.c +66 -77
  280. data/vendor/libgit2/src/transports/winhttp.c +314 -318
  281. data/vendor/libgit2/src/tree-cache.c +12 -19
  282. data/vendor/libgit2/src/tree.c +142 -103
  283. data/vendor/libgit2/src/tree.h +12 -1
  284. data/vendor/libgit2/src/unix/map.c +3 -3
  285. data/vendor/libgit2/src/unix/posix.h +11 -1
  286. data/vendor/libgit2/src/userdiff.h +1 -3
  287. data/vendor/libgit2/src/util.c +56 -70
  288. data/vendor/libgit2/src/util.h +156 -28
  289. data/vendor/libgit2/src/vector.c +4 -4
  290. data/vendor/libgit2/src/win32/dir.c +3 -3
  291. data/vendor/libgit2/src/win32/findfile.c +3 -3
  292. data/vendor/libgit2/src/win32/map.c +11 -9
  293. data/vendor/libgit2/src/win32/msvc-compat.h +0 -6
  294. data/vendor/libgit2/src/win32/path_w32.c +9 -113
  295. data/vendor/libgit2/src/win32/path_w32.h +29 -18
  296. data/vendor/libgit2/src/win32/posix.h +4 -1
  297. data/vendor/libgit2/src/win32/posix_w32.c +45 -70
  298. data/vendor/libgit2/src/win32/precompiled.h +2 -0
  299. data/vendor/libgit2/src/win32/thread.c +10 -5
  300. data/vendor/libgit2/src/win32/w32_buffer.c +5 -9
  301. data/vendor/libgit2/src/win32/w32_crtdbg_stacktrace.c +2 -3
  302. data/vendor/libgit2/src/win32/w32_crtdbg_stacktrace.h +75 -26
  303. data/vendor/libgit2/src/win32/w32_stack.c +11 -6
  304. data/vendor/libgit2/src/win32/w32_stack.h +3 -3
  305. data/vendor/libgit2/src/win32/w32_util.c +64 -27
  306. data/vendor/libgit2/src/win32/w32_util.h +49 -5
  307. data/vendor/libgit2/src/worktree.c +60 -95
  308. data/vendor/libgit2/src/worktree.h +0 -2
  309. data/vendor/libgit2/src/xdiff/xdiffi.c +5 -7
  310. data/vendor/libgit2/src/xdiff/xhistogram.c +1 -1
  311. data/vendor/libgit2/src/xdiff/xmerge.c +15 -27
  312. data/vendor/libgit2/src/xdiff/xpatience.c +0 -3
  313. data/vendor/libgit2/src/zstream.c +4 -4
  314. metadata +33 -122
  315. data/vendor/libgit2/cmake/Modules/FindGSSFramework.cmake +0 -28
  316. data/vendor/libgit2/cmake/Modules/FindPCRE.cmake +0 -38
  317. data/vendor/libgit2/cmake/Modules/FindPCRE2.cmake +0 -37
  318. data/vendor/libgit2/cmake/Modules/FindmbedTLS.cmake +0 -93
  319. data/vendor/libgit2/cmake/Modules/PkgBuildConfig.cmake +0 -110
  320. data/vendor/libgit2/cmake/Modules/SelectGSSAPI.cmake +0 -53
  321. data/vendor/libgit2/cmake/Modules/SelectHTTPSBackend.cmake +0 -124
  322. data/vendor/libgit2/cmake/Modules/SelectHashes.cmake +0 -66
  323. data/vendor/libgit2/deps/ntlmclient/CMakeLists.txt +0 -21
  324. data/vendor/libgit2/deps/ntlmclient/compat.h +0 -33
  325. data/vendor/libgit2/deps/ntlmclient/crypt.h +0 -64
  326. data/vendor/libgit2/deps/ntlmclient/crypt_commoncrypto.c +0 -120
  327. data/vendor/libgit2/deps/ntlmclient/crypt_commoncrypto.h +0 -18
  328. data/vendor/libgit2/deps/ntlmclient/crypt_mbedtls.c +0 -145
  329. data/vendor/libgit2/deps/ntlmclient/crypt_mbedtls.h +0 -18
  330. data/vendor/libgit2/deps/ntlmclient/crypt_openssl.c +0 -130
  331. data/vendor/libgit2/deps/ntlmclient/crypt_openssl.h +0 -21
  332. data/vendor/libgit2/deps/ntlmclient/ntlm.c +0 -1420
  333. data/vendor/libgit2/deps/ntlmclient/ntlm.h +0 -174
  334. data/vendor/libgit2/deps/ntlmclient/ntlmclient.h +0 -320
  335. data/vendor/libgit2/deps/ntlmclient/unicode.h +0 -36
  336. data/vendor/libgit2/deps/ntlmclient/unicode_builtin.c +0 -445
  337. data/vendor/libgit2/deps/ntlmclient/unicode_iconv.c +0 -201
  338. data/vendor/libgit2/deps/ntlmclient/utf8.h +0 -1257
  339. data/vendor/libgit2/deps/ntlmclient/util.c +0 -21
  340. data/vendor/libgit2/deps/ntlmclient/util.h +0 -14
  341. data/vendor/libgit2/deps/pcre/CMakeLists.txt +0 -140
  342. data/vendor/libgit2/deps/pcre/COPYING +0 -5
  343. data/vendor/libgit2/deps/pcre/cmake/COPYING-CMAKE-SCRIPTS +0 -22
  344. data/vendor/libgit2/deps/pcre/cmake/FindEditline.cmake +0 -17
  345. data/vendor/libgit2/deps/pcre/cmake/FindPackageHandleStandardArgs.cmake +0 -58
  346. data/vendor/libgit2/deps/pcre/cmake/FindReadline.cmake +0 -29
  347. data/vendor/libgit2/deps/pcre/config.h.in +0 -57
  348. data/vendor/libgit2/deps/pcre/pcre.h +0 -641
  349. data/vendor/libgit2/deps/pcre/pcre_byte_order.c +0 -319
  350. data/vendor/libgit2/deps/pcre/pcre_chartables.c +0 -198
  351. data/vendor/libgit2/deps/pcre/pcre_compile.c +0 -9800
  352. data/vendor/libgit2/deps/pcre/pcre_config.c +0 -190
  353. data/vendor/libgit2/deps/pcre/pcre_dfa_exec.c +0 -3676
  354. data/vendor/libgit2/deps/pcre/pcre_exec.c +0 -7173
  355. data/vendor/libgit2/deps/pcre/pcre_fullinfo.c +0 -245
  356. data/vendor/libgit2/deps/pcre/pcre_get.c +0 -669
  357. data/vendor/libgit2/deps/pcre/pcre_globals.c +0 -86
  358. data/vendor/libgit2/deps/pcre/pcre_internal.h +0 -2787
  359. data/vendor/libgit2/deps/pcre/pcre_jit_compile.c +0 -11913
  360. data/vendor/libgit2/deps/pcre/pcre_maketables.c +0 -156
  361. data/vendor/libgit2/deps/pcre/pcre_newline.c +0 -210
  362. data/vendor/libgit2/deps/pcre/pcre_ord2utf8.c +0 -94
  363. data/vendor/libgit2/deps/pcre/pcre_printint.c +0 -834
  364. data/vendor/libgit2/deps/pcre/pcre_refcount.c +0 -92
  365. data/vendor/libgit2/deps/pcre/pcre_string_utils.c +0 -211
  366. data/vendor/libgit2/deps/pcre/pcre_study.c +0 -1686
  367. data/vendor/libgit2/deps/pcre/pcre_tables.c +0 -727
  368. data/vendor/libgit2/deps/pcre/pcre_ucd.c +0 -3644
  369. data/vendor/libgit2/deps/pcre/pcre_valid_utf8.c +0 -301
  370. data/vendor/libgit2/deps/pcre/pcre_version.c +0 -98
  371. data/vendor/libgit2/deps/pcre/pcre_xclass.c +0 -268
  372. data/vendor/libgit2/deps/pcre/pcreposix.c +0 -421
  373. data/vendor/libgit2/deps/pcre/pcreposix.h +0 -117
  374. data/vendor/libgit2/deps/pcre/ucp.h +0 -224
  375. data/vendor/libgit2/deps/winhttp/COPYING.GPL +0 -993
  376. data/vendor/libgit2/deps/winhttp/COPYING.LGPL +0 -502
  377. data/vendor/libgit2/deps/zlib/COPYING +0 -27
  378. data/vendor/libgit2/include/git2/apply.h +0 -149
  379. data/vendor/libgit2/include/git2/cert.h +0 -135
  380. data/vendor/libgit2/include/git2/cred.h +0 -308
  381. data/vendor/libgit2/include/git2/deprecated.h +0 -493
  382. data/vendor/libgit2/include/git2/mailmap.h +0 -115
  383. data/vendor/libgit2/include/git2/sys/alloc.h +0 -101
  384. data/vendor/libgit2/include/git2/sys/cred.h +0 -90
  385. data/vendor/libgit2/include/git2/sys/path.h +0 -64
  386. data/vendor/libgit2/src/alloc.c +0 -43
  387. data/vendor/libgit2/src/alloc.h +0 -40
  388. data/vendor/libgit2/src/allocators/stdalloc.c +0 -119
  389. data/vendor/libgit2/src/allocators/win32_crtdbg.c +0 -118
  390. data/vendor/libgit2/src/config_backend.h +0 -96
  391. data/vendor/libgit2/src/config_entries.c +0 -229
  392. data/vendor/libgit2/src/config_entries.h +0 -24
  393. data/vendor/libgit2/src/config_mem.c +0 -220
  394. data/vendor/libgit2/src/config_snapshot.c +0 -206
  395. data/vendor/libgit2/src/errors.h +0 -81
  396. data/vendor/libgit2/src/hash/sha1.h +0 -38
  397. data/vendor/libgit2/src/hash/sha1/collisiondetect.c +0 -48
  398. data/vendor/libgit2/src/hash/sha1/collisiondetect.h +0 -19
  399. data/vendor/libgit2/src/hash/sha1/common_crypto.h +0 -19
  400. data/vendor/libgit2/src/hash/sha1/mbedtls.c +0 -46
  401. data/vendor/libgit2/src/hash/sha1/mbedtls.h +0 -19
  402. data/vendor/libgit2/src/hash/sha1/openssl.c +0 -59
  403. data/vendor/libgit2/src/hash/sha1/openssl.h +0 -19
  404. data/vendor/libgit2/src/mailmap.c +0 -485
  405. data/vendor/libgit2/src/mailmap.h +0 -35
  406. data/vendor/libgit2/src/net.c +0 -184
  407. data/vendor/libgit2/src/net.h +0 -36
  408. data/vendor/libgit2/src/reader.c +0 -265
  409. data/vendor/libgit2/src/reader.h +0 -107
  410. data/vendor/libgit2/src/regexp.c +0 -221
  411. data/vendor/libgit2/src/regexp.h +0 -97
  412. data/vendor/libgit2/src/streams/mbedtls.c +0 -483
  413. data/vendor/libgit2/src/streams/mbedtls.h +0 -23
  414. data/vendor/libgit2/src/streams/registry.c +0 -118
  415. data/vendor/libgit2/src/streams/registry.h +0 -19
  416. data/vendor/libgit2/src/transports/auth_ntlm.c +0 -223
  417. data/vendor/libgit2/src/transports/auth_ntlm.h +0 -35
  418. data/vendor/libgit2/src/wildmatch.c +0 -320
  419. data/vendor/libgit2/src/wildmatch.h +0 -23
  420. data/vendor/libgit2/src/win32/w32_common.h +0 -39
@@ -24,7 +24,7 @@
24
24
 
25
25
  struct git_config {
26
26
  git_refcount rc;
27
- git_vector backends;
27
+ git_vector files;
28
28
  };
29
29
 
30
30
  extern int git_config__global_location(git_buf *buf);
@@ -34,6 +34,19 @@ extern int git_config_rename_section(
34
34
  const char *old_section_name, /* eg "branch.dummy" */
35
35
  const char *new_section_name); /* NULL to drop the old section */
36
36
 
37
+ /**
38
+ * Create a configuration file backend for ondisk files
39
+ *
40
+ * These are the normal `.gitconfig` files that Core Git
41
+ * processes. Note that you first have to add this file to a
42
+ * configuration object before you can query it for configuration
43
+ * variables.
44
+ *
45
+ * @param out the new backend
46
+ * @param path where the config file is located
47
+ */
48
+ extern int git_config_file__ondisk(git_config_backend **out, const char *path);
49
+
37
50
  extern int git_config__normalize_name(const char *in, char **out);
38
51
 
39
52
  /* internal only: does not normalize key and sets out to NULL if not found */
@@ -66,19 +79,18 @@ extern int git_config__get_bool_force(
66
79
  extern int git_config__get_int_force(
67
80
  const git_config *cfg, const char *key, int fallback_value);
68
81
 
69
- /* API for repository configmap-style lookups from config - not cached, but
70
- * uses configmap value maps and fallbacks
82
+ /* API for repository cvar-style lookups from config - not cached, but
83
+ * uses cvar value maps and fallbacks
71
84
  */
72
- extern int git_config__configmap_lookup(
73
- int *out, git_config *config, git_configmap_item item);
85
+ extern int git_config__cvar(
86
+ int *out, git_config *config, git_cvar_cached cvar);
74
87
 
75
88
  /**
76
89
  * The opposite of git_config_lookup_map_value, we take an enum value
77
90
  * and map it to the string or bool value on the config.
78
91
  */
79
- int git_config_lookup_map_enum(git_configmap_t *type_out,
80
- const char **str_out, const git_configmap *maps,
81
- size_t map_n, int enum_val);
92
+ int git_config_lookup_map_enum(git_cvar_t *type_out, const char **str_out,
93
+ const git_cvar_map *maps, size_t map_n, int enum_val);
82
94
 
83
95
  /**
84
96
  * Unlock the backend with the highest priority
@@ -7,7 +7,7 @@
7
7
 
8
8
  #include "common.h"
9
9
 
10
- #include "futils.h"
10
+ #include "fileops.h"
11
11
  #include "repository.h"
12
12
  #include "config.h"
13
13
  #include "git2/config.h"
@@ -15,8 +15,8 @@
15
15
  #include "filter.h"
16
16
 
17
17
  struct map_data {
18
- const char *name;
19
- git_configmap *maps;
18
+ const char *cvar_name;
19
+ git_cvar_map *maps;
20
20
  size_t map_count;
21
21
  int default_value;
22
22
  };
@@ -29,11 +29,11 @@ struct map_data {
29
29
  * value is native. See gitattributes(5) for more information on
30
30
  * end-of-line conversion.
31
31
  */
32
- static git_configmap _configmap_eol[] = {
33
- {GIT_CONFIGMAP_FALSE, NULL, GIT_EOL_UNSET},
34
- {GIT_CONFIGMAP_STRING, "lf", GIT_EOL_LF},
35
- {GIT_CONFIGMAP_STRING, "crlf", GIT_EOL_CRLF},
36
- {GIT_CONFIGMAP_STRING, "native", GIT_EOL_NATIVE}
32
+ static git_cvar_map _cvar_map_eol[] = {
33
+ {GIT_CVAR_FALSE, NULL, GIT_EOL_UNSET},
34
+ {GIT_CVAR_STRING, "lf", GIT_EOL_LF},
35
+ {GIT_CVAR_STRING, "crlf", GIT_EOL_CRLF},
36
+ {GIT_CVAR_STRING, "native", GIT_EOL_NATIVE}
37
37
  };
38
38
 
39
39
  /*
@@ -46,55 +46,49 @@ static git_configmap _configmap_eol[] = {
46
46
  * does not have normalized line endings. This variable can be set to input,
47
47
  * in which case no output conversion is performed.
48
48
  */
49
- static git_configmap _configmap_autocrlf[] = {
50
- {GIT_CONFIGMAP_FALSE, NULL, GIT_AUTO_CRLF_FALSE},
51
- {GIT_CONFIGMAP_TRUE, NULL, GIT_AUTO_CRLF_TRUE},
52
- {GIT_CONFIGMAP_STRING, "input", GIT_AUTO_CRLF_INPUT}
49
+ static git_cvar_map _cvar_map_autocrlf[] = {
50
+ {GIT_CVAR_FALSE, NULL, GIT_AUTO_CRLF_FALSE},
51
+ {GIT_CVAR_TRUE, NULL, GIT_AUTO_CRLF_TRUE},
52
+ {GIT_CVAR_STRING, "input", GIT_AUTO_CRLF_INPUT}
53
53
  };
54
54
 
55
- static git_configmap _configmap_safecrlf[] = {
56
- {GIT_CONFIGMAP_FALSE, NULL, GIT_SAFE_CRLF_FALSE},
57
- {GIT_CONFIGMAP_TRUE, NULL, GIT_SAFE_CRLF_FAIL},
58
- {GIT_CONFIGMAP_STRING, "warn", GIT_SAFE_CRLF_WARN}
59
- };
60
-
61
- static git_configmap _configmap_logallrefupdates[] = {
62
- {GIT_CONFIGMAP_FALSE, NULL, GIT_LOGALLREFUPDATES_FALSE},
63
- {GIT_CONFIGMAP_TRUE, NULL, GIT_LOGALLREFUPDATES_TRUE},
64
- {GIT_CONFIGMAP_STRING, "always", GIT_LOGALLREFUPDATES_ALWAYS},
55
+ static git_cvar_map _cvar_map_safecrlf[] = {
56
+ {GIT_CVAR_FALSE, NULL, GIT_SAFE_CRLF_FALSE},
57
+ {GIT_CVAR_TRUE, NULL, GIT_SAFE_CRLF_FAIL},
58
+ {GIT_CVAR_STRING, "warn", GIT_SAFE_CRLF_WARN}
65
59
  };
66
60
 
67
61
  /*
68
62
  * Generic map for integer values
69
63
  */
70
- static git_configmap _configmap_int[] = {
71
- {GIT_CONFIGMAP_INT32, NULL, 0},
64
+ static git_cvar_map _cvar_map_int[] = {
65
+ {GIT_CVAR_INT32, NULL, 0},
72
66
  };
73
67
 
74
- static struct map_data _configmaps[] = {
75
- {"core.autocrlf", _configmap_autocrlf, ARRAY_SIZE(_configmap_autocrlf), GIT_AUTO_CRLF_DEFAULT},
76
- {"core.eol", _configmap_eol, ARRAY_SIZE(_configmap_eol), GIT_EOL_DEFAULT},
68
+ static struct map_data _cvar_maps[] = {
69
+ {"core.autocrlf", _cvar_map_autocrlf, ARRAY_SIZE(_cvar_map_autocrlf), GIT_AUTO_CRLF_DEFAULT},
70
+ {"core.eol", _cvar_map_eol, ARRAY_SIZE(_cvar_map_eol), GIT_EOL_DEFAULT},
77
71
  {"core.symlinks", NULL, 0, GIT_SYMLINKS_DEFAULT },
78
72
  {"core.ignorecase", NULL, 0, GIT_IGNORECASE_DEFAULT },
79
73
  {"core.filemode", NULL, 0, GIT_FILEMODE_DEFAULT },
80
74
  {"core.ignorestat", NULL, 0, GIT_IGNORESTAT_DEFAULT },
81
75
  {"core.trustctime", NULL, 0, GIT_TRUSTCTIME_DEFAULT },
82
- {"core.abbrev", _configmap_int, 1, GIT_ABBREV_DEFAULT },
76
+ {"core.abbrev", _cvar_map_int, 1, GIT_ABBREV_DEFAULT },
83
77
  {"core.precomposeunicode", NULL, 0, GIT_PRECOMPOSE_DEFAULT },
84
- {"core.safecrlf", _configmap_safecrlf, ARRAY_SIZE(_configmap_safecrlf), GIT_SAFE_CRLF_DEFAULT},
85
- {"core.logallrefupdates", _configmap_logallrefupdates, ARRAY_SIZE(_configmap_logallrefupdates), GIT_LOGALLREFUPDATES_DEFAULT},
78
+ {"core.safecrlf", _cvar_map_safecrlf, ARRAY_SIZE(_cvar_map_safecrlf), GIT_SAFE_CRLF_DEFAULT},
79
+ {"core.logallrefupdates", NULL, 0, GIT_LOGALLREFUPDATES_DEFAULT },
86
80
  {"core.protecthfs", NULL, 0, GIT_PROTECTHFS_DEFAULT },
87
81
  {"core.protectntfs", NULL, 0, GIT_PROTECTNTFS_DEFAULT },
88
82
  {"core.fsyncobjectfiles", NULL, 0, GIT_FSYNCOBJECTFILES_DEFAULT },
89
83
  };
90
84
 
91
- int git_config__configmap_lookup(int *out, git_config *config, git_configmap_item item)
85
+ int git_config__cvar(int *out, git_config *config, git_cvar_cached cvar)
92
86
  {
93
87
  int error = 0;
94
- struct map_data *data = &_configmaps[(int)item];
88
+ struct map_data *data = &_cvar_maps[(int)cvar];
95
89
  git_config_entry *entry;
96
90
 
97
- if ((error = git_config__lookup_entry(&entry, config, data->name, false)) < 0)
91
+ if ((error = git_config__lookup_entry(&entry, config, data->cvar_name, false)) < 0)
98
92
  return error;
99
93
 
100
94
  if (!entry)
@@ -109,29 +103,29 @@ int git_config__configmap_lookup(int *out, git_config *config, git_configmap_ite
109
103
  return error;
110
104
  }
111
105
 
112
- int git_repository__configmap_lookup(int *out, git_repository *repo, git_configmap_item item)
106
+ int git_repository__cvar(int *out, git_repository *repo, git_cvar_cached cvar)
113
107
  {
114
- *out = repo->configmap_cache[(int)item];
108
+ *out = repo->cvar_cache[(int)cvar];
115
109
 
116
- if (*out == GIT_CONFIGMAP_NOT_CACHED) {
110
+ if (*out == GIT_CVAR_NOT_CACHED) {
117
111
  int error;
118
112
  git_config *config;
119
113
 
120
114
  if ((error = git_repository_config__weakptr(&config, repo)) < 0 ||
121
- (error = git_config__configmap_lookup(out, config, item)) < 0)
115
+ (error = git_config__cvar(out, config, cvar)) < 0)
122
116
  return error;
123
117
 
124
- repo->configmap_cache[(int)item] = *out;
118
+ repo->cvar_cache[(int)cvar] = *out;
125
119
  }
126
120
 
127
121
  return 0;
128
122
  }
129
123
 
130
- void git_repository__configmap_lookup_cache_clear(git_repository *repo)
124
+ void git_repository__cvar_cache_clear(git_repository *repo)
131
125
  {
132
126
  int i;
133
127
 
134
- for (i = 0; i < GIT_CONFIGMAP_CACHE_MAX; ++i)
135
- repo->configmap_cache[i] = GIT_CONFIGMAP_NOT_CACHED;
128
+ for (i = 0; i < GIT_CVAR_CACHE_MAX; ++i)
129
+ repo->cvar_cache[i] = GIT_CVAR_NOT_CACHED;
136
130
  }
137
131
 
@@ -5,37 +5,93 @@
5
5
  * a Linking Exception. For full terms see the included COPYING file.
6
6
  */
7
7
 
8
- #include "config.h"
8
+ #include "config_file.h"
9
9
 
10
+ #include "config.h"
11
+ #include "filebuf.h"
12
+ #include "sysdir.h"
13
+ #include "buffer.h"
14
+ #include "buf_text.h"
10
15
  #include "git2/config.h"
11
16
  #include "git2/sys/config.h"
12
-
17
+ #include "git2/types.h"
18
+ #include "strmap.h"
13
19
  #include "array.h"
14
- #include "buffer.h"
15
- #include "config_backend.h"
16
- #include "config_entries.h"
17
20
  #include "config_parse.h"
18
- #include "filebuf.h"
19
- #include "regexp.h"
20
- #include "sysdir.h"
21
- #include "wildmatch.h"
21
+
22
+ #include <ctype.h>
23
+ #include <sys/types.h>
24
+ #include <regex.h>
25
+
26
+ typedef struct cvar_t {
27
+ struct cvar_t *next;
28
+ git_config_entry *entry;
29
+ bool included; /* whether this is part of [include] */
30
+ } cvar_t;
31
+
32
+ typedef struct git_config_file_iter {
33
+ git_config_iterator parent;
34
+ git_strmap_iter iter;
35
+ cvar_t* next_var;
36
+ } git_config_file_iter;
22
37
 
23
38
  /* Max depth for [include] directives */
24
39
  #define MAX_INCLUDE_DEPTH 10
25
40
 
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;
41
+ #define CVAR_LIST_HEAD(list) ((list)->head)
42
+
43
+ #define CVAR_LIST_TAIL(list) ((list)->tail)
44
+
45
+ #define CVAR_LIST_NEXT(var) ((var)->next)
46
+
47
+ #define CVAR_LIST_EMPTY(list) ((list)->head == NULL)
48
+
49
+ #define CVAR_LIST_APPEND(list, var) do {\
50
+ if (CVAR_LIST_EMPTY(list)) {\
51
+ CVAR_LIST_HEAD(list) = CVAR_LIST_TAIL(list) = var;\
52
+ } else {\
53
+ CVAR_LIST_NEXT(CVAR_LIST_TAIL(list)) = var;\
54
+ CVAR_LIST_TAIL(list) = var;\
55
+ }\
56
+ } while(0)
57
+
58
+ #define CVAR_LIST_REMOVE_HEAD(list) do {\
59
+ CVAR_LIST_HEAD(list) = CVAR_LIST_NEXT(CVAR_LIST_HEAD(list));\
60
+ } while(0)
61
+
62
+ #define CVAR_LIST_REMOVE_AFTER(var) do {\
63
+ CVAR_LIST_NEXT(var) = CVAR_LIST_NEXT(CVAR_LIST_NEXT(var));\
64
+ } while(0)
65
+
66
+ #define CVAR_LIST_FOREACH(list, iter)\
67
+ for ((iter) = CVAR_LIST_HEAD(list);\
68
+ (iter) != NULL;\
69
+ (iter) = CVAR_LIST_NEXT(iter))
70
+
71
+ /*
72
+ * Inspired by the FreeBSD functions
73
+ */
74
+ #define CVAR_LIST_FOREACH_SAFE(start, iter, tmp)\
75
+ for ((iter) = CVAR_LIST_HEAD(vars);\
76
+ (iter) && (((tmp) = CVAR_LIST_NEXT(iter) || 1));\
77
+ (iter) = (tmp))
78
+
79
+ typedef struct {
80
+ git_atomic refcount;
81
+ git_strmap *values;
82
+ } refcounted_strmap;
32
83
 
33
84
  typedef struct {
34
85
  git_config_backend parent;
86
+ /* mutex to coordinate accessing the values */
35
87
  git_mutex values_mutex;
36
- git_config_entries *entries;
88
+ refcounted_strmap *values;
37
89
  const git_repository *repo;
38
90
  git_config_level_t level;
91
+ } diskfile_header;
92
+
93
+ typedef struct {
94
+ diskfile_header header;
39
95
 
40
96
  git_array_t(git_config_parser) readers;
41
97
 
@@ -43,47 +99,158 @@ typedef struct {
43
99
  git_filebuf locked_buf;
44
100
  git_buf locked_content;
45
101
 
46
- config_file file;
47
- } config_file_backend;
102
+ struct config_file file;
103
+ } diskfile_backend;
48
104
 
49
105
  typedef struct {
50
- const git_repository *repo;
51
- config_file *file;
52
- git_config_entries *entries;
53
- git_config_level_t level;
54
- unsigned int depth;
55
- } config_file_parse_data;
106
+ diskfile_header header;
107
+
108
+ diskfile_backend *snapshot_from;
109
+ } diskfile_readonly_backend;
56
110
 
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);
111
+ static int config_read(git_strmap *values, const git_repository *repo, git_config_file *file, git_config_level_t level, int depth);
112
+ static int config_write(diskfile_backend *cfg, const char *orig_key, const char *key, const regex_t *preg, const char *value);
60
113
  static char *escape_value(const char *ptr);
61
114
 
115
+ int git_config_file__snapshot(git_config_backend **out, diskfile_backend *in);
116
+ static int config_snapshot(git_config_backend **out, git_config_backend *in);
117
+
118
+ static int config_error_readonly(void)
119
+ {
120
+ giterr_set(GITERR_CONFIG, "this backend is read-only");
121
+ return -1;
122
+ }
123
+
124
+ static void cvar_free(cvar_t *var)
125
+ {
126
+ if (var == NULL)
127
+ return;
128
+
129
+ git__free((char*)var->entry->name);
130
+ git__free((char *)var->entry->value);
131
+ git__free(var->entry);
132
+ git__free(var);
133
+ }
134
+
135
+ int git_config_file_normalize_section(char *start, char *end)
136
+ {
137
+ char *scan;
138
+
139
+ if (start == end)
140
+ return GIT_EINVALIDSPEC;
141
+
142
+ /* Validate and downcase range */
143
+ for (scan = start; *scan; ++scan) {
144
+ if (end && scan >= end)
145
+ break;
146
+ if (isalnum(*scan))
147
+ *scan = (char)git__tolower(*scan);
148
+ else if (*scan != '-' || scan == start)
149
+ return GIT_EINVALIDSPEC;
150
+ }
151
+
152
+ if (scan == start)
153
+ return GIT_EINVALIDSPEC;
154
+
155
+ return 0;
156
+ }
157
+
158
+ /* Add or append the new config option */
159
+ static int append_entry(git_strmap *values, cvar_t *var)
160
+ {
161
+ git_strmap_iter pos;
162
+ cvar_t *existing;
163
+ int error = 0;
164
+
165
+ pos = git_strmap_lookup_index(values, var->entry->name);
166
+ if (!git_strmap_valid_index(values, pos)) {
167
+ git_strmap_insert(values, var->entry->name, var, &error);
168
+ } else {
169
+ existing = git_strmap_value_at(values, pos);
170
+ while (existing->next != NULL) {
171
+ existing = existing->next;
172
+ }
173
+ existing->next = var;
174
+ }
175
+
176
+ if (error > 0)
177
+ error = 0;
178
+
179
+ return error;
180
+ }
181
+
182
+ static void free_vars(git_strmap *values)
183
+ {
184
+ cvar_t *var = NULL;
185
+
186
+ if (values == NULL)
187
+ return;
188
+
189
+ git_strmap_foreach_value(values, var,
190
+ while (var != NULL) {
191
+ cvar_t *next = CVAR_LIST_NEXT(var);
192
+ cvar_free(var);
193
+ var = next;
194
+ });
195
+
196
+ git_strmap_free(values);
197
+ }
198
+
199
+ static void refcounted_strmap_free(refcounted_strmap *map)
200
+ {
201
+ if (!map)
202
+ return;
203
+
204
+ if (git_atomic_dec(&map->refcount) != 0)
205
+ return;
206
+
207
+ free_vars(map->values);
208
+ git__free(map);
209
+ }
210
+
62
211
  /**
63
212
  * Take the current values map from the backend and increase its
64
213
  * refcount. This is its own function to make sure we use the mutex to
65
214
  * avoid the map pointer from changing under us.
66
215
  */
67
- static int config_file_entries_take(git_config_entries **out, config_file_backend *b)
216
+ static refcounted_strmap *refcounted_strmap_take(diskfile_header *h)
68
217
  {
69
- int error;
218
+ refcounted_strmap *map;
70
219
 
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;
220
+ if (git_mutex_lock(&h->values_mutex) < 0) {
221
+ giterr_set(GITERR_OS, "failed to lock config backend");
222
+ return NULL;
74
223
  }
75
224
 
76
- git_config_entries_incref(b->entries);
77
- *out = b->entries;
225
+ map = h->values;
226
+ git_atomic_inc(&map->refcount);
78
227
 
79
- git_mutex_unlock(&b->values_mutex);
228
+ git_mutex_unlock(&h->values_mutex);
80
229
 
81
- return 0;
230
+ return map;
82
231
  }
83
232
 
84
- static void config_file_clear(config_file *file)
233
+ static int refcounted_strmap_alloc(refcounted_strmap **out)
85
234
  {
86
- config_file *include;
235
+ refcounted_strmap *map;
236
+ int error;
237
+
238
+ map = git__calloc(1, sizeof(refcounted_strmap));
239
+ GITERR_CHECK_ALLOC(map);
240
+
241
+ git_atomic_set(&map->refcount, 1);
242
+
243
+ if ((error = git_strmap_alloc(&map->values)) < 0)
244
+ git__free(map);
245
+ else
246
+ *out = map;
247
+
248
+ return error;
249
+ }
250
+
251
+ static void config_file_clear(struct config_file *file)
252
+ {
253
+ struct config_file *include;
87
254
  uint32_t i;
88
255
 
89
256
  if (file == NULL)
@@ -97,31 +264,31 @@ static void config_file_clear(config_file *file)
97
264
  git__free(file->path);
98
265
  }
99
266
 
100
- static int config_file_open(git_config_backend *cfg, git_config_level_t level, const git_repository *repo)
267
+ static int config_open(git_config_backend *cfg, git_config_level_t level, const git_repository *repo)
101
268
  {
102
- config_file_backend *b = GIT_CONTAINER_OF(cfg, config_file_backend, parent);
103
269
  int res;
270
+ diskfile_backend *b = (diskfile_backend *)cfg;
104
271
 
105
- b->level = level;
106
- b->repo = repo;
272
+ b->header.level = level;
273
+ b->header.repo = repo;
107
274
 
108
- if ((res = git_config_entries_new(&b->entries)) < 0)
275
+ if ((res = refcounted_strmap_alloc(&b->header.values)) < 0)
109
276
  return res;
110
277
 
111
278
  if (!git_path_exists(b->file.path))
112
279
  return 0;
113
280
 
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;
281
+ if (res < 0 || (res = config_read(b->header.values->values, repo, &b->file, level, 0)) < 0) {
282
+ refcounted_strmap_free(b->header.values);
283
+ b->header.values = NULL;
117
284
  }
118
285
 
119
286
  return res;
120
287
  }
121
288
 
122
- static int config_file_is_modified(int *modified, config_file *file)
289
+ static int config_is_modified(int *modified, struct config_file *file)
123
290
  {
124
- config_file *include;
291
+ git_config_file *include;
125
292
  git_buf buf = GIT_BUF_INIT;
126
293
  git_oid hash;
127
294
  uint32_t i;
@@ -129,9 +296,6 @@ static int config_file_is_modified(int *modified, config_file *file)
129
296
 
130
297
  *modified = 0;
131
298
 
132
- if (!git_futils_filestamp_check(&file->stamp, file->path))
133
- goto check_includes;
134
-
135
299
  if ((error = git_futils_readbuffer(&buf, file->path)) < 0)
136
300
  goto out;
137
301
 
@@ -143,305 +307,388 @@ static int config_file_is_modified(int *modified, config_file *file)
143
307
  goto out;
144
308
  }
145
309
 
146
- check_includes:
147
310
  git_array_foreach(file->includes, i, include) {
148
- if ((error = config_file_is_modified(modified, include)) < 0 || *modified)
311
+ if ((error = config_is_modified(modified, include)) < 0 || *modified)
149
312
  goto out;
150
313
  }
151
314
 
152
315
  out:
153
- git_buf_dispose(&buf);
316
+ git_buf_free(&buf);
154
317
 
155
318
  return error;
156
319
  }
157
320
 
158
- static int config_file_set_entries(git_config_backend *cfg, git_config_entries *entries)
321
+ static int config_refresh(git_config_backend *cfg)
159
322
  {
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;
323
+ diskfile_backend *b = (diskfile_backend *)cfg;
324
+ refcounted_strmap *values = NULL, *tmp;
325
+ git_config_file *include;
326
+ int error, modified;
164
327
  uint32_t i;
165
328
 
166
- if (b->parent.readonly) {
167
- git_error_set(GIT_ERROR_CONFIG, "this backend is read-only");
168
- return -1;
169
- }
329
+ if (b->header.parent.readonly)
330
+ return config_error_readonly();
170
331
 
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");
332
+ error = config_is_modified(&modified, &b->file);
333
+ if (error < 0 && error != GIT_ENOTFOUND)
177
334
  goto out;
178
- }
179
-
180
- old = b->entries;
181
- b->entries = entries;
182
-
183
- git_mutex_unlock(&b->values_mutex);
184
-
185
- out:
186
- git_config_entries_free(old);
187
- return error;
188
- }
189
335
 
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;
336
+ if (!modified)
337
+ return 0;
195
338
 
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)
339
+ if ((error = refcounted_strmap_alloc(&values)) < 0)
200
340
  goto out;
201
341
 
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;
342
+ /* Reparse the current configuration */
343
+ git_array_foreach(b->file.includes, i, include) {
344
+ config_file_clear(include);
345
+ }
346
+ git_array_clear(b->file.includes);
213
347
 
214
- if (cfg->readonly)
215
- return 0;
348
+ if ((error = config_read(values->values, b->header.repo, &b->file, b->header.level, 0)) < 0)
349
+ goto out;
216
350
 
217
- if ((error = config_file_is_modified(&modified, &b->file)) < 0 && error != GIT_ENOTFOUND)
351
+ if ((error = git_mutex_lock(&b->header.values_mutex)) < 0) {
352
+ giterr_set(GITERR_OS, "failed to lock config backend");
218
353
  goto out;
354
+ }
219
355
 
220
- if (!modified)
221
- return 0;
356
+ tmp = b->header.values;
357
+ b->header.values = values;
358
+ values = tmp;
222
359
 
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;
360
+ git_mutex_unlock(&b->header.values_mutex);
227
361
 
228
- entries = NULL;
229
362
  out:
230
- git_config_entries_free(entries);
363
+ refcounted_strmap_free(values);
231
364
 
232
365
  return (error == GIT_ENOTFOUND) ? 0 : error;
233
366
  }
234
367
 
235
- static void config_file_free(git_config_backend *_backend)
368
+ static void backend_free(git_config_backend *_backend)
236
369
  {
237
- config_file_backend *backend = GIT_CONTAINER_OF(_backend, config_file_backend, parent);
370
+ diskfile_backend *backend = (diskfile_backend *)_backend;
238
371
 
239
372
  if (backend == NULL)
240
373
  return;
241
374
 
242
375
  config_file_clear(&backend->file);
243
- git_config_entries_free(backend->entries);
244
- git_mutex_free(&backend->values_mutex);
376
+ refcounted_strmap_free(backend->header.values);
377
+ git_mutex_free(&backend->header.values_mutex);
245
378
  git__free(backend);
246
379
  }
247
380
 
248
- static int config_file_iterator(
249
- git_config_iterator **iter,
250
- struct git_config_backend *backend)
381
+ static void config_iterator_free(
382
+ git_config_iterator* iter)
251
383
  {
252
- config_file_backend *b = GIT_CONTAINER_OF(backend, config_file_backend, parent);
253
- git_config_entries *dupped = NULL, *entries = NULL;
254
- int error;
255
-
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;
261
-
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;
384
+ iter->backend->free(iter->backend);
385
+ git__free(iter);
267
386
  }
268
387
 
269
- static int config_file_snapshot(git_config_backend **out, git_config_backend *backend)
388
+ static int config_iterator_next(
389
+ git_config_entry **entry,
390
+ git_config_iterator *iter)
270
391
  {
271
- return git_config_backend_snapshot(out, backend);
392
+ git_config_file_iter *it = (git_config_file_iter *) iter;
393
+ diskfile_header *h = (diskfile_header *) it->parent.backend;
394
+ git_strmap *values = h->values->values;
395
+ int err = 0;
396
+ cvar_t * var;
397
+
398
+ if (it->next_var == NULL) {
399
+ err = git_strmap_next((void**) &var, &(it->iter), values);
400
+ } else {
401
+ var = it->next_var;
402
+ }
403
+
404
+ if (err < 0) {
405
+ it->next_var = NULL;
406
+ return err;
407
+ }
408
+
409
+ *entry = var->entry;
410
+ it->next_var = CVAR_LIST_NEXT(var);
411
+
412
+ return 0;
272
413
  }
273
414
 
274
- static int config_file_set(git_config_backend *cfg, const char *name, const char *value)
415
+ static int config_iterator_new(
416
+ git_config_iterator **iter,
417
+ struct git_config_backend* backend)
275
418
  {
276
- config_file_backend *b = GIT_CONTAINER_OF(cfg, config_file_backend, parent);
277
- git_config_entries *entries;
278
- git_config_entry *existing;
279
- char *key, *esc_value = NULL;
419
+ diskfile_header *h;
420
+ git_config_file_iter *it;
421
+ git_config_backend *snapshot;
422
+ diskfile_header *bh = (diskfile_header *) backend;
280
423
  int error;
281
424
 
282
- if ((error = git_config__normalize_name(name, &key)) < 0)
425
+ if ((error = config_snapshot(&snapshot, backend)) < 0)
283
426
  return error;
284
427
 
285
- if ((error = config_file_entries_take(&entries, b)) < 0)
428
+ if ((error = snapshot->open(snapshot, bh->level, bh->repo)) < 0)
286
429
  return error;
287
430
 
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)
431
+ it = git__calloc(1, sizeof(git_config_file_iter));
432
+ GITERR_CHECK_ALLOC(it);
433
+
434
+ h = (diskfile_header *)snapshot;
435
+
436
+ /* strmap_begin() is currently a macro returning 0 */
437
+ GIT_UNUSED(h);
438
+
439
+ it->parent.backend = snapshot;
440
+ it->iter = git_strmap_begin(h->values);
441
+ it->next_var = NULL;
442
+
443
+ it->parent.next = config_iterator_next;
444
+ it->parent.free = config_iterator_free;
445
+ *iter = (git_config_iterator *) it;
446
+
447
+ return 0;
448
+ }
449
+
450
+ static int config_set(git_config_backend *cfg, const char *name, const char *value)
451
+ {
452
+ diskfile_backend *b = (diskfile_backend *)cfg;
453
+ refcounted_strmap *map;
454
+ git_strmap *values;
455
+ char *key, *esc_value = NULL;
456
+ khiter_t pos;
457
+ int rval, ret;
458
+
459
+ if ((rval = git_config__normalize_name(name, &key)) < 0)
460
+ return rval;
461
+
462
+ if ((map = refcounted_strmap_take(&b->header)) == NULL)
463
+ return -1;
464
+ values = map->values;
465
+
466
+ /*
467
+ * Try to find it in the existing values and update it if it
468
+ * only has one value.
469
+ */
470
+ pos = git_strmap_lookup_index(values, key);
471
+ if (git_strmap_valid_index(values, pos)) {
472
+ cvar_t *existing = git_strmap_value_at(values, pos);
473
+
474
+ if (existing->next != NULL) {
475
+ giterr_set(GITERR_CONFIG, "multivar incompatible with simple set");
476
+ ret = -1;
291
477
  goto out;
292
- error = 0;
293
- } else if ((!existing->value && !value) ||
294
- (existing->value && value && !strcmp(existing->value, value))) {
478
+ }
479
+
480
+ if (existing->included) {
481
+ giterr_set(GITERR_CONFIG, "modifying included variable is not supported");
482
+ ret = -1;
483
+ goto out;
484
+ }
485
+
295
486
  /* don't update if old and new values already match */
296
- error = 0;
297
- goto out;
487
+ if ((!existing->entry->value && !value) ||
488
+ (existing->entry->value && value &&
489
+ !strcmp(existing->entry->value, value))) {
490
+ ret = 0;
491
+ goto out;
492
+ }
298
493
  }
299
494
 
300
495
  /* No early returns due to sanity checks, let's write it out and refresh */
496
+
301
497
  if (value) {
302
498
  esc_value = escape_value(value);
303
- GIT_ERROR_CHECK_ALLOC(esc_value);
499
+ GITERR_CHECK_ALLOC(esc_value);
304
500
  }
305
501
 
306
- if ((error = config_file_write(b, name, key, NULL, esc_value)) < 0)
502
+ if ((ret = config_write(b, name, key, NULL, esc_value)) < 0)
307
503
  goto out;
308
504
 
505
+ ret = config_refresh(cfg);
506
+
309
507
  out:
310
- git_config_entries_free(entries);
508
+ refcounted_strmap_free(map);
311
509
  git__free(esc_value);
312
510
  git__free(key);
313
- return error;
511
+ return ret;
314
512
  }
315
513
 
316
514
  /* release the map containing the entry as an equivalent to freeing it */
317
- static void config_file_entry_free(git_config_entry *entry)
515
+ static void release_map(git_config_entry *entry)
318
516
  {
319
- git_config_entries *entries = (git_config_entries *) entry->payload;
320
- git_config_entries_free(entries);
517
+ refcounted_strmap *map = (refcounted_strmap *) entry->payload;
518
+ refcounted_strmap_free(map);
321
519
  }
322
520
 
323
521
  /*
324
522
  * Internal function that actually gets the value in string form
325
523
  */
326
- static int config_file_get(git_config_backend *cfg, const char *key, git_config_entry **out)
524
+ static int config_get(git_config_backend *cfg, const char *key, git_config_entry **out)
327
525
  {
328
- config_file_backend *h = GIT_CONTAINER_OF(cfg, config_file_backend, parent);
329
- git_config_entries *entries = NULL;
330
- git_config_entry *entry;
526
+ diskfile_header *h = (diskfile_header *)cfg;
527
+ refcounted_strmap *map;
528
+ git_strmap *values;
529
+ khiter_t pos;
530
+ cvar_t *var;
331
531
  int error = 0;
332
532
 
333
- if (!h->parent.readonly && ((error = config_file_refresh(cfg)) < 0))
533
+ if (!h->parent.readonly && ((error = config_refresh(cfg)) < 0))
334
534
  return error;
335
535
 
336
- if ((error = config_file_entries_take(&entries, h)) < 0)
337
- return error;
536
+ if ((map = refcounted_strmap_take(h)) == NULL)
537
+ return -1;
538
+ values = map->values;
338
539
 
339
- if ((error = (git_config_entries_get(&entry, entries, key))) < 0) {
340
- git_config_entries_free(entries);
341
- return error;
540
+ pos = git_strmap_lookup_index(values, key);
541
+
542
+ /* no error message; the config system will write one */
543
+ if (!git_strmap_valid_index(values, pos)) {
544
+ refcounted_strmap_free(map);
545
+ return GIT_ENOTFOUND;
342
546
  }
343
547
 
344
- entry->free = config_file_entry_free;
345
- entry->payload = entries;
346
- *out = entry;
548
+ var = git_strmap_value_at(values, pos);
549
+ while (var->next)
550
+ var = var->next;
347
551
 
348
- return 0;
552
+ *out = var->entry;
553
+ (*out)->free = release_map;
554
+ (*out)->payload = map;
555
+
556
+ return error;
349
557
  }
350
558
 
351
- static int config_file_set_multivar(
559
+ static int config_set_multivar(
352
560
  git_config_backend *cfg, const char *name, const char *regexp, const char *value)
353
561
  {
354
- config_file_backend *b = GIT_CONTAINER_OF(cfg, config_file_backend, parent);
355
- git_regexp preg;
356
- int result;
562
+ diskfile_backend *b = (diskfile_backend *)cfg;
357
563
  char *key;
564
+ regex_t preg;
565
+ int result;
358
566
 
359
567
  assert(regexp);
360
568
 
361
569
  if ((result = git_config__normalize_name(name, &key)) < 0)
362
570
  return result;
363
571
 
364
- if ((result = git_regexp_compile(&preg, regexp, 0)) < 0)
572
+ result = p_regcomp(&preg, regexp, REG_EXTENDED);
573
+ if (result != 0) {
574
+ giterr_set_regex(&preg, result);
575
+ result = -1;
365
576
  goto out;
577
+ }
366
578
 
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)
579
+ /* If we do have it, set call config_write() and reload */
580
+ if ((result = config_write(b, name, key, &preg, value)) < 0)
369
581
  goto out;
370
582
 
583
+ result = config_refresh(cfg);
584
+
371
585
  out:
372
586
  git__free(key);
373
- git_regexp_dispose(&preg);
587
+ regfree(&preg);
374
588
 
375
589
  return result;
376
590
  }
377
591
 
378
- static int config_file_delete(git_config_backend *cfg, const char *name)
592
+ static int config_delete(git_config_backend *cfg, const char *name)
379
593
  {
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;
594
+ cvar_t *var;
595
+ diskfile_backend *b = (diskfile_backend *)cfg;
596
+ refcounted_strmap *map; git_strmap *values;
597
+ char *key;
598
+ int result;
599
+ khiter_t pos;
385
600
 
386
- if ((error = git_config__normalize_name(name, &key)) < 0)
387
- goto out;
601
+ if ((result = git_config__normalize_name(name, &key)) < 0)
602
+ return result;
388
603
 
389
- if ((error = config_file_entries_take(&entries, b)) < 0)
390
- goto out;
604
+ if ((map = refcounted_strmap_take(&b->header)) == NULL)
605
+ return -1;
606
+ values = b->header.values->values;
391
607
 
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;
608
+ pos = git_strmap_lookup_index(values, key);
609
+ git__free(key);
610
+
611
+ if (!git_strmap_valid_index(values, pos)) {
612
+ refcounted_strmap_free(map);
613
+ giterr_set(GITERR_CONFIG, "could not find key '%s' to delete", name);
614
+ return GIT_ENOTFOUND;
397
615
  }
398
616
 
399
- if ((error = config_file_write(b, name, entry->name, NULL, NULL)) < 0)
400
- goto out;
617
+ var = git_strmap_value_at(values, pos);
618
+ refcounted_strmap_free(map);
401
619
 
402
- out:
403
- git_config_entries_free(entries);
404
- git__free(key);
405
- return error;
620
+ if (var->included) {
621
+ giterr_set(GITERR_CONFIG, "cannot delete included variable");
622
+ return -1;
623
+ }
624
+
625
+ if (var->next != NULL) {
626
+ giterr_set(GITERR_CONFIG, "cannot delete multivar with a single delete");
627
+ return -1;
628
+ }
629
+
630
+ if ((result = config_write(b, name, var->entry->name, NULL, NULL)) < 0)
631
+ return result;
632
+
633
+ return config_refresh(cfg);
406
634
  }
407
635
 
408
- static int config_file_delete_multivar(git_config_backend *cfg, const char *name, const char *regexp)
636
+ static int config_delete_multivar(git_config_backend *cfg, const char *name, const char *regexp)
409
637
  {
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;
638
+ diskfile_backend *b = (diskfile_backend *)cfg;
639
+ refcounted_strmap *map;
640
+ git_strmap *values;
641
+ char *key;
642
+ regex_t preg;
415
643
  int result;
644
+ khiter_t pos;
416
645
 
417
646
  if ((result = git_config__normalize_name(name, &key)) < 0)
418
- goto out;
647
+ return result;
419
648
 
420
- if ((result = config_file_entries_take(&entries, b)) < 0)
421
- goto out;
649
+ if ((map = refcounted_strmap_take(&b->header)) == NULL)
650
+ return -1;
651
+ values = b->header.values->values;
422
652
 
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);
426
- goto out;
653
+ pos = git_strmap_lookup_index(values, key);
654
+
655
+ if (!git_strmap_valid_index(values, pos)) {
656
+ refcounted_strmap_free(map);
657
+ git__free(key);
658
+ giterr_set(GITERR_CONFIG, "could not find key '%s' to delete", name);
659
+ return GIT_ENOTFOUND;
427
660
  }
428
661
 
429
- if ((result = git_regexp_compile(&preg, regexp, 0)) < 0)
662
+ refcounted_strmap_free(map);
663
+
664
+ result = p_regcomp(&preg, regexp, REG_EXTENDED);
665
+ if (result != 0) {
666
+ giterr_set_regex(&preg, result);
667
+ result = -1;
430
668
  goto out;
669
+ }
431
670
 
432
- if ((result = config_file_write(b, name, key, &preg, NULL)) < 0)
671
+ if ((result = config_write(b, name, key, &preg, NULL)) < 0)
433
672
  goto out;
434
673
 
674
+ result = config_refresh(cfg);
675
+
435
676
  out:
436
- git_config_entries_free(entries);
437
677
  git__free(key);
438
- git_regexp_dispose(&preg);
678
+ regfree(&preg);
439
679
  return result;
440
680
  }
441
681
 
442
- static int config_file_lock(git_config_backend *_cfg)
682
+ static int config_snapshot(git_config_backend **out, git_config_backend *in)
683
+ {
684
+ diskfile_backend *b = (diskfile_backend *) in;
685
+
686
+ return git_config_file__snapshot(out, b);
687
+ }
688
+
689
+ static int config_lock(git_config_backend *_cfg)
443
690
  {
444
- config_file_backend *cfg = GIT_CONTAINER_OF(_cfg, config_file_backend, parent);
691
+ diskfile_backend *cfg = (diskfile_backend *) _cfg;
445
692
  int error;
446
693
 
447
694
  if ((error = git_filebuf_open(&cfg->locked_buf, cfg->file.path, 0, GIT_CONFIG_FILE_MODE)) < 0)
@@ -458,9 +705,9 @@ static int config_file_lock(git_config_backend *_cfg)
458
705
 
459
706
  }
460
707
 
461
- static int config_file_unlock(git_config_backend *_cfg, int success)
708
+ static int config_unlock(git_config_backend *_cfg, int success)
462
709
  {
463
- config_file_backend *cfg = GIT_CONTAINER_OF(_cfg, config_file_backend, parent);
710
+ diskfile_backend *cfg = (diskfile_backend *) _cfg;
464
711
  int error = 0;
465
712
 
466
713
  if (success) {
@@ -469,37 +716,153 @@ static int config_file_unlock(git_config_backend *_cfg, int success)
469
716
  }
470
717
 
471
718
  git_filebuf_cleanup(&cfg->locked_buf);
472
- git_buf_dispose(&cfg->locked_content);
719
+ git_buf_free(&cfg->locked_content);
473
720
  cfg->locked = false;
474
721
 
475
722
  return error;
476
723
  }
477
724
 
478
- int git_config_backend_from_file(git_config_backend **out, const char *path)
725
+ int git_config_file__ondisk(git_config_backend **out, const char *path)
479
726
  {
480
- config_file_backend *backend;
727
+ diskfile_backend *backend;
481
728
 
482
- backend = git__calloc(1, sizeof(config_file_backend));
483
- GIT_ERROR_CHECK_ALLOC(backend);
729
+ backend = git__calloc(1, sizeof(diskfile_backend));
730
+ GITERR_CHECK_ALLOC(backend);
484
731
 
485
- backend->parent.version = GIT_CONFIG_BACKEND_VERSION;
486
- git_mutex_init(&backend->values_mutex);
732
+ backend->header.parent.version = GIT_CONFIG_BACKEND_VERSION;
733
+ git_mutex_init(&backend->header.values_mutex);
487
734
 
488
735
  backend->file.path = git__strdup(path);
489
- GIT_ERROR_CHECK_ALLOC(backend->file.path);
736
+ GITERR_CHECK_ALLOC(backend->file.path);
490
737
  git_array_init(backend->file.includes);
491
738
 
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;
739
+ backend->header.parent.open = config_open;
740
+ backend->header.parent.get = config_get;
741
+ backend->header.parent.set = config_set;
742
+ backend->header.parent.set_multivar = config_set_multivar;
743
+ backend->header.parent.del = config_delete;
744
+ backend->header.parent.del_multivar = config_delete_multivar;
745
+ backend->header.parent.iterator = config_iterator_new;
746
+ backend->header.parent.snapshot = config_snapshot;
747
+ backend->header.parent.lock = config_lock;
748
+ backend->header.parent.unlock = config_unlock;
749
+ backend->header.parent.free = backend_free;
750
+
751
+ *out = (git_config_backend *)backend;
752
+
753
+ return 0;
754
+ }
755
+
756
+ static int config_set_readonly(git_config_backend *cfg, const char *name, const char *value)
757
+ {
758
+ GIT_UNUSED(cfg);
759
+ GIT_UNUSED(name);
760
+ GIT_UNUSED(value);
761
+
762
+ return config_error_readonly();
763
+ }
764
+
765
+ static int config_set_multivar_readonly(
766
+ git_config_backend *cfg, const char *name, const char *regexp, const char *value)
767
+ {
768
+ GIT_UNUSED(cfg);
769
+ GIT_UNUSED(name);
770
+ GIT_UNUSED(regexp);
771
+ GIT_UNUSED(value);
772
+
773
+ return config_error_readonly();
774
+ }
775
+
776
+ static int config_delete_multivar_readonly(git_config_backend *cfg, const char *name, const char *regexp)
777
+ {
778
+ GIT_UNUSED(cfg);
779
+ GIT_UNUSED(name);
780
+ GIT_UNUSED(regexp);
781
+
782
+ return config_error_readonly();
783
+ }
784
+
785
+ static int config_delete_readonly(git_config_backend *cfg, const char *name)
786
+ {
787
+ GIT_UNUSED(cfg);
788
+ GIT_UNUSED(name);
789
+
790
+ return config_error_readonly();
791
+ }
792
+
793
+ static int config_lock_readonly(git_config_backend *_cfg)
794
+ {
795
+ GIT_UNUSED(_cfg);
796
+
797
+ return config_error_readonly();
798
+ }
799
+
800
+ static int config_unlock_readonly(git_config_backend *_cfg, int success)
801
+ {
802
+ GIT_UNUSED(_cfg);
803
+ GIT_UNUSED(success);
804
+
805
+ return config_error_readonly();
806
+ }
807
+
808
+ static void backend_readonly_free(git_config_backend *_backend)
809
+ {
810
+ diskfile_backend *backend = (diskfile_backend *)_backend;
811
+
812
+ if (backend == NULL)
813
+ return;
814
+
815
+ refcounted_strmap_free(backend->header.values);
816
+ git_mutex_free(&backend->header.values_mutex);
817
+ git__free(backend);
818
+ }
819
+
820
+ static int config_readonly_open(git_config_backend *cfg, git_config_level_t level, const git_repository *repo)
821
+ {
822
+ diskfile_readonly_backend *b = (diskfile_readonly_backend *) cfg;
823
+ diskfile_backend *src = b->snapshot_from;
824
+ diskfile_header *src_header = &src->header;
825
+ refcounted_strmap *src_map;
826
+ int error;
827
+
828
+ if (!src_header->parent.readonly && (error = config_refresh(&src_header->parent)) < 0)
829
+ return error;
830
+
831
+ /* We're just copying data, don't care about the level or repo*/
832
+ GIT_UNUSED(level);
833
+ GIT_UNUSED(repo);
834
+
835
+ if ((src_map = refcounted_strmap_take(src_header)) == NULL)
836
+ return -1;
837
+ b->header.values = src_map;
838
+
839
+ return 0;
840
+ }
841
+
842
+ int git_config_file__snapshot(git_config_backend **out, diskfile_backend *in)
843
+ {
844
+ diskfile_readonly_backend *backend;
845
+
846
+ backend = git__calloc(1, sizeof(diskfile_readonly_backend));
847
+ GITERR_CHECK_ALLOC(backend);
848
+
849
+ backend->header.parent.version = GIT_CONFIG_BACKEND_VERSION;
850
+ git_mutex_init(&backend->header.values_mutex);
851
+
852
+ backend->snapshot_from = in;
853
+
854
+ backend->header.parent.readonly = 1;
855
+ backend->header.parent.version = GIT_CONFIG_BACKEND_VERSION;
856
+ backend->header.parent.open = config_readonly_open;
857
+ backend->header.parent.get = config_get;
858
+ backend->header.parent.set = config_set_readonly;
859
+ backend->header.parent.set_multivar = config_set_multivar_readonly;
860
+ backend->header.parent.del = config_delete_readonly;
861
+ backend->header.parent.del_multivar = config_delete_multivar_readonly;
862
+ backend->header.parent.iterator = config_iterator_new;
863
+ backend->header.parent.lock = config_lock_readonly;
864
+ backend->header.parent.unlock = config_unlock_readonly;
865
+ backend->header.parent.free = backend_readonly_free;
503
866
 
504
867
  *out = (git_config_backend *)backend;
505
868
 
@@ -541,15 +904,26 @@ static char *escape_value(const char *ptr)
541
904
  ptr++;
542
905
  }
543
906
 
544
- if (git_buf_oom(&buf))
907
+ if (git_buf_oom(&buf)) {
908
+ git_buf_free(&buf);
545
909
  return NULL;
910
+ }
546
911
 
547
912
  return git_buf_detach(&buf);
548
913
  }
549
914
 
550
- static int parse_include(config_file_parse_data *parse_data, const char *file)
915
+ struct parse_data {
916
+ const git_repository *repo;
917
+ const char *file_path;
918
+ git_strmap *values;
919
+ git_config_level_t level;
920
+ int depth;
921
+ };
922
+
923
+ static int parse_include(git_config_parser *reader,
924
+ struct parse_data *parse_data, const char *file)
551
925
  {
552
- config_file *include;
926
+ struct config_file *include;
553
927
  git_buf path = GIT_BUF_INIT;
554
928
  char *dir;
555
929
  int result;
@@ -557,7 +931,7 @@ static int parse_include(config_file_parse_data *parse_data, const char *file)
557
931
  if (!file)
558
932
  return 0;
559
933
 
560
- if ((result = git_path_dirname_r(&path, parse_data->file->path)) < 0)
934
+ if ((result = git_path_dirname_r(&path, reader->file->path)) < 0)
561
935
  return result;
562
936
 
563
937
  dir = git_buf_detach(&path);
@@ -567,17 +941,16 @@ static int parse_include(config_file_parse_data *parse_data, const char *file)
567
941
  if (result < 0)
568
942
  return result;
569
943
 
570
- include = git_array_alloc(parse_data->file->includes);
571
- GIT_ERROR_CHECK_ALLOC(include);
944
+ include = git_array_alloc(reader->file->includes);
572
945
  memset(include, 0, sizeof(*include));
573
946
  git_array_init(include->includes);
574
947
  include->path = git_buf_detach(&path);
575
948
 
576
- result = config_file_read(parse_data->entries, parse_data->repo, include,
577
- parse_data->level, parse_data->depth+1);
949
+ result = config_read(parse_data->values, parse_data->repo,
950
+ include, parse_data->level, parse_data->depth+1);
578
951
 
579
952
  if (result == GIT_ENOTFOUND) {
580
- git_error_clear();
953
+ giterr_clear();
581
954
  result = 0;
582
955
  }
583
956
 
@@ -588,41 +961,41 @@ static int do_match_gitdir(
588
961
  int *matches,
589
962
  const git_repository *repo,
590
963
  const char *cfg_file,
591
- const char *condition,
964
+ const char *value,
592
965
  bool case_insensitive)
593
966
  {
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);
967
+ git_buf path = GIT_BUF_INIT;
968
+ int error, fnmatch_flags;
969
+
970
+ if (value[0] == '.' && git_path_is_dirsep(value[1])) {
971
+ git_path_dirname_r(&path, cfg_file);
972
+ git_buf_joinpath(&path, path.ptr, value + 2);
973
+ } else if (value[0] == '~' && git_path_is_dirsep(value[1]))
974
+ git_sysdir_expand_global_file(&path, value + 1);
975
+ else if (!git_path_is_absolute(value))
976
+ git_buf_joinpath(&path, "**", value);
604
977
  else
605
- git_buf_sets(&pattern, condition);
978
+ git_buf_sets(&path, value);
606
979
 
607
- if (git_path_is_dirsep(condition[strlen(condition) - 1]))
608
- git_buf_puts(&pattern, "**");
609
-
610
- if (git_buf_oom(&pattern)) {
980
+ if (git_buf_oom(&path)) {
611
981
  error = -1;
612
982
  goto out;
613
983
  }
614
984
 
615
- if ((error = git_repository_item_path(&gitdir, repo, GIT_REPOSITORY_ITEM_GITDIR)) < 0)
985
+ if (git_path_is_dirsep(value[strlen(value) - 1]))
986
+ git_buf_puts(&path, "**");
987
+
988
+ fnmatch_flags = FNM_PATHNAME|FNM_LEADING_DIR;
989
+ if (case_insensitive)
990
+ fnmatch_flags |= FNM_IGNORECASE;
991
+
992
+ if ((error = p_fnmatch(path.ptr, git_repository_path(repo), fnmatch_flags)) < 0)
616
993
  goto out;
617
994
 
618
- if (git_path_is_dirsep(gitdir.ptr[gitdir.size - 1]))
619
- git_buf_truncate(&gitdir, gitdir.size - 1);
995
+ *matches = (error == 0);
620
996
 
621
- *matches = wildmatch(pattern.ptr, gitdir.ptr,
622
- WM_PATHNAME | (case_insensitive ? WM_CASEFOLD : 0)) == WM_MATCH;
623
997
  out:
624
- git_buf_dispose(&pattern);
625
- git_buf_dispose(&gitdir);
998
+ git_buf_free(&path);
626
999
  return error;
627
1000
  }
628
1001
 
@@ -644,67 +1017,16 @@ static int conditional_match_gitdir_i(
644
1017
  return do_match_gitdir(matches, repo, cfg_file, value, true);
645
1018
  }
646
1019
 
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
-
698
1020
  static const struct {
699
1021
  const char *prefix;
700
1022
  int (*matches)(int *matches, const git_repository *repo, const char *cfg, const char *value);
701
1023
  } conditions[] = {
702
1024
  { "gitdir:", conditional_match_gitdir },
703
- { "gitdir/i:", conditional_match_gitdir_i },
704
- { "onbranch:", conditional_match_onbranch }
1025
+ { "gitdir/i:", conditional_match_gitdir_i }
705
1026
  };
706
1027
 
707
- static int parse_conditional_include(config_file_parse_data *parse_data, const char *section, const char *file)
1028
+ static int parse_conditional_include(git_config_parser *reader,
1029
+ struct parse_data *parse_data, const char *section, const char *file)
708
1030
  {
709
1031
  char *condition;
710
1032
  size_t i;
@@ -722,12 +1044,12 @@ static int parse_conditional_include(config_file_parse_data *parse_data, const c
722
1044
 
723
1045
  if ((error = conditions[i].matches(&matches,
724
1046
  parse_data->repo,
725
- parse_data->file->path,
1047
+ parse_data->file_path,
726
1048
  condition + strlen(conditions[i].prefix))) < 0)
727
1049
  break;
728
1050
 
729
1051
  if (matches)
730
- error = parse_include(parse_data, file);
1052
+ error = parse_include(reader, parse_data, file);
731
1053
 
732
1054
  break;
733
1055
  }
@@ -739,19 +1061,17 @@ static int parse_conditional_include(config_file_parse_data *parse_data, const c
739
1061
  static int read_on_variable(
740
1062
  git_config_parser *reader,
741
1063
  const char *current_section,
742
- const char *var_name,
743
- const char *var_value,
1064
+ char *var_name,
1065
+ char *var_value,
744
1066
  const char *line,
745
1067
  size_t line_len,
746
1068
  void *data)
747
1069
  {
748
- config_file_parse_data *parse_data = (config_file_parse_data *)data;
1070
+ struct parse_data *parse_data = (struct parse_data *)data;
749
1071
  git_buf buf = GIT_BUF_INIT;
750
- git_config_entry *entry;
751
- const char *c;
1072
+ cvar_t *var;
752
1073
  int result = 0;
753
1074
 
754
- GIT_UNUSED(reader);
755
1075
  GIT_UNUSED(line);
756
1076
  GIT_UNUSED(line_len);
757
1077
 
@@ -763,104 +1083,85 @@ static int read_on_variable(
763
1083
  git_buf_puts(&buf, current_section);
764
1084
  git_buf_putc(&buf, '.');
765
1085
  }
1086
+ git__strtolower(var_name);
1087
+ git_buf_puts(&buf, var_name);
1088
+ git__free(var_name);
766
1089
 
767
- for (c = var_name; *c; c++)
768
- git_buf_putc(&buf, git__tolower(*c));
769
-
770
- if (git_buf_oom(&buf))
1090
+ if (git_buf_oom(&buf)) {
1091
+ git__free(var_value);
771
1092
  return -1;
1093
+ }
1094
+
1095
+ var = git__calloc(1, sizeof(cvar_t));
1096
+ GITERR_CHECK_ALLOC(var);
1097
+ var->entry = git__calloc(1, sizeof(git_config_entry));
1098
+ GITERR_CHECK_ALLOC(var->entry);
772
1099
 
773
- entry = git__calloc(1, sizeof(git_config_entry));
774
- GIT_ERROR_CHECK_ALLOC(entry);
775
- entry->name = git_buf_detach(&buf);
776
- entry->value = var_value ? git__strdup(var_value) : NULL;
777
- entry->level = parse_data->level;
778
- entry->include_depth = parse_data->depth;
1100
+ var->entry->name = git_buf_detach(&buf);
1101
+ var->entry->value = var_value;
1102
+ var->entry->level = parse_data->level;
1103
+ var->included = !!parse_data->depth;
779
1104
 
780
- if ((result = git_config_entries_append(parse_data->entries, entry)) < 0)
1105
+ if ((result = append_entry(parse_data->values, var)) < 0)
781
1106
  return result;
782
1107
 
783
1108
  result = 0;
784
1109
 
785
1110
  /* Add or append the new config option */
786
- if (!git__strcmp(entry->name, "include.path"))
787
- result = parse_include(parse_data, entry->value);
788
- else if (!git__prefixcmp(entry->name, "includeif.") &&
789
- !git__suffixcmp(entry->name, ".path"))
790
- result = parse_conditional_include(parse_data, entry->name, entry->value);
1111
+ if (!git__strcmp(var->entry->name, "include.path"))
1112
+ result = parse_include(reader, parse_data, var->entry->value);
1113
+ else if (!git__prefixcmp(var->entry->name, "includeif.") &&
1114
+ !git__suffixcmp(var->entry->name, ".path"))
1115
+ result = parse_conditional_include(reader, parse_data,
1116
+ var->entry->name, var->entry->value);
1117
+
791
1118
 
792
1119
  return result;
793
1120
  }
794
1121
 
795
- static int config_file_read_buffer(
796
- git_config_entries *entries,
1122
+ static int config_read(
1123
+ git_strmap *values,
797
1124
  const git_repository *repo,
798
- config_file *file,
1125
+ git_config_file *file,
799
1126
  git_config_level_t level,
800
- int depth,
801
- const char *buf,
802
- size_t buflen)
1127
+ int depth)
803
1128
  {
804
- config_file_parse_data parse_data;
1129
+ struct parse_data parse_data;
805
1130
  git_config_parser reader;
1131
+ git_buf contents = GIT_BUF_INIT;
806
1132
  int error;
807
1133
 
808
1134
  if (depth >= MAX_INCLUDE_DEPTH) {
809
- git_error_set(GIT_ERROR_CONFIG, "maximum config include depth reached");
1135
+ giterr_set(GITERR_CONFIG, "maximum config include depth reached");
810
1136
  return -1;
811
1137
  }
812
1138
 
1139
+ if ((error = git_futils_readbuffer(&contents, file->path)) < 0)
1140
+ goto out;
1141
+
1142
+ git_parse_ctx_init(&reader.ctx, contents.ptr, contents.size);
1143
+
1144
+ if ((error = git_hash_buf(&file->checksum, contents.ptr, contents.size)) < 0)
1145
+ goto out;
1146
+
813
1147
  /* Initialize the reading position */
814
- reader.path = file->path;
815
- git_parse_ctx_init(&reader.ctx, buf, buflen);
1148
+ reader.file = file;
1149
+ git_parse_ctx_init(&reader.ctx, contents.ptr, contents.size);
816
1150
 
817
1151
  /* If the file is empty, there's nothing for us to do */
818
- if (!reader.ctx.content || *reader.ctx.content == '\0') {
819
- error = 0;
1152
+ if (!reader.ctx.content || *reader.ctx.content == '\0')
820
1153
  goto out;
821
- }
822
1154
 
823
1155
  parse_data.repo = repo;
824
- parse_data.file = file;
825
- parse_data.entries = entries;
1156
+ parse_data.file_path = file->path;
1157
+ parse_data.values = values;
826
1158
  parse_data.level = level;
827
1159
  parse_data.depth = depth;
828
1160
 
829
1161
  error = git_config_parse(&reader, NULL, read_on_variable, NULL, NULL, &parse_data);
830
1162
 
831
1163
  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
-
862
- out:
863
- git_buf_dispose(&contents);
1164
+ git_buf_free(&contents);
864
1165
  return error;
865
1166
  }
866
1167
 
@@ -879,7 +1180,7 @@ static int write_section(git_buf *fbuf, const char *key)
879
1180
  char *escaped;
880
1181
  git_buf_put(&buf, key, dot - key);
881
1182
  escaped = escape_value(dot + 1);
882
- GIT_ERROR_CHECK_ALLOC(escaped);
1183
+ GITERR_CHECK_ALLOC(escaped);
883
1184
  git_buf_printf(&buf, " \"%s\"", escaped);
884
1185
  git__free(escaped);
885
1186
  }
@@ -889,7 +1190,7 @@ static int write_section(git_buf *fbuf, const char *key)
889
1190
  return -1;
890
1191
 
891
1192
  result = git_buf_put(fbuf, git_buf_cstr(&buf), buf.size);
892
- git_buf_dispose(&buf);
1193
+ git_buf_free(&buf);
893
1194
 
894
1195
  return result;
895
1196
  }
@@ -921,7 +1222,7 @@ struct write_data {
921
1222
  const char *section;
922
1223
  const char *orig_name;
923
1224
  const char *name;
924
- const git_regexp *preg;
1225
+ const regex_t *preg;
925
1226
  const char *value;
926
1227
  };
927
1228
 
@@ -998,8 +1299,8 @@ static int write_on_section(
998
1299
  static int write_on_variable(
999
1300
  git_config_parser *reader,
1000
1301
  const char *current_section,
1001
- const char *var_name,
1002
- const char *var_value,
1302
+ char *var_name,
1303
+ char *var_value,
1003
1304
  const char *line,
1004
1305
  size_t line_len,
1005
1306
  void *data)
@@ -1026,7 +1327,10 @@ static int write_on_variable(
1026
1327
 
1027
1328
  /* If we have a regex to match the value, see if it matches */
1028
1329
  if (has_matched && write_data->preg != NULL)
1029
- has_matched = (git_regexp_match(write_data->preg, var_value) == 0);
1330
+ has_matched = (regexec(write_data->preg, var_value, 0, NULL, 0) == 0);
1331
+
1332
+ git__free(var_name);
1333
+ git__free(var_value);
1030
1334
 
1031
1335
  /* If this isn't the name/value we're looking for, simply dump the
1032
1336
  * existing data back out and continue on.
@@ -1087,79 +1391,89 @@ static int write_on_eof(
1087
1391
  /*
1088
1392
  * This is pretty much the parsing, except we write out anything we don't have
1089
1393
  */
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
-
1394
+ static int config_write(diskfile_backend *cfg, const char *orig_key, const char *key, const regex_t *preg, const char* value)
1092
1395
  {
1093
- char *orig_section = NULL, *section = NULL, *orig_name, *name, *ldot;
1094
- git_buf buf = GIT_BUF_INIT, contents = GIT_BUF_INIT;
1095
- git_config_parser parser = GIT_CONFIG_PARSER_INIT;
1396
+ int result;
1397
+ char *orig_section, *section, *orig_name, *name, *ldot;
1096
1398
  git_filebuf file = GIT_FILEBUF_INIT;
1399
+ git_buf buf = GIT_BUF_INIT, contents = GIT_BUF_INIT;
1400
+ git_config_parser reader;
1097
1401
  struct write_data write_data;
1098
- int error;
1099
1402
 
1100
- memset(&write_data, 0, sizeof(write_data));
1403
+ memset(&reader, 0, sizeof(reader));
1404
+ reader.file = &cfg->file;
1101
1405
 
1102
1406
  if (cfg->locked) {
1103
- error = git_buf_puts(&contents, git_buf_cstr(&cfg->locked_content) == NULL ? "" : git_buf_cstr(&cfg->locked_content));
1407
+ result = git_buf_puts(&contents, git_buf_cstr(&cfg->locked_content));
1104
1408
  } else {
1105
- if ((error = git_filebuf_open(&file, cfg->file.path, GIT_FILEBUF_HASH_CONTENTS,
1106
- GIT_CONFIG_FILE_MODE)) < 0)
1107
- goto done;
1409
+ /* Lock the file */
1410
+ if ((result = git_filebuf_open(
1411
+ &file, cfg->file.path, GIT_FILEBUF_HASH_CONTENTS, GIT_CONFIG_FILE_MODE)) < 0) {
1412
+ git_buf_free(&contents);
1413
+ return result;
1414
+ }
1108
1415
 
1109
1416
  /* We need to read in our own config file */
1110
- error = git_futils_readbuffer(&contents, cfg->file.path);
1417
+ result = git_futils_readbuffer(&contents, cfg->file.path);
1111
1418
  }
1112
- if (error < 0 && error != GIT_ENOTFOUND)
1113
- goto done;
1114
1419
 
1115
- if ((git_config_parser_init(&parser, cfg->file.path, contents.ptr, contents.size)) < 0)
1116
- goto done;
1420
+ /* Initialise the reading position */
1421
+ if (result == 0 || result == GIT_ENOTFOUND) {
1422
+ git_parse_ctx_init(&reader.ctx, contents.ptr, contents.size);
1423
+ } else {
1424
+ git_filebuf_cleanup(&file);
1425
+ return -1; /* OS error when reading the file */
1426
+ }
1117
1427
 
1118
1428
  ldot = strrchr(key, '.');
1119
1429
  name = ldot + 1;
1120
1430
  section = git__strndup(key, ldot - key);
1121
- GIT_ERROR_CHECK_ALLOC(section);
1431
+ GITERR_CHECK_ALLOC(section);
1122
1432
 
1123
1433
  ldot = strrchr(orig_key, '.');
1124
1434
  orig_name = ldot + 1;
1125
1435
  orig_section = git__strndup(orig_key, ldot - orig_key);
1126
- GIT_ERROR_CHECK_ALLOC(orig_section);
1436
+ GITERR_CHECK_ALLOC(orig_section);
1127
1437
 
1128
1438
  write_data.buf = &buf;
1439
+ git_buf_init(&write_data.buffered_comment, 0);
1129
1440
  write_data.orig_section = orig_section;
1130
1441
  write_data.section = section;
1442
+ write_data.in_section = 0;
1443
+ write_data.preg_replaced = 0;
1131
1444
  write_data.orig_name = orig_name;
1132
1445
  write_data.name = name;
1133
1446
  write_data.preg = preg;
1134
1447
  write_data.value = value;
1135
1448
 
1136
- if ((error = git_config_parse(&parser, write_on_section, write_on_variable,
1137
- write_on_comment, write_on_eof, &write_data)) < 0)
1449
+ result = git_config_parse(&reader,
1450
+ write_on_section,
1451
+ write_on_variable,
1452
+ write_on_comment,
1453
+ write_on_eof,
1454
+ &write_data);
1455
+ git__free(section);
1456
+ git__free(orig_section);
1457
+ git_buf_free(&write_data.buffered_comment);
1458
+
1459
+ if (result < 0) {
1460
+ git_filebuf_cleanup(&file);
1138
1461
  goto done;
1462
+ }
1139
1463
 
1140
1464
  if (cfg->locked) {
1141
1465
  size_t len = buf.asize;
1142
1466
  /* Update our copy with the modified contents */
1143
- git_buf_dispose(&cfg->locked_content);
1467
+ git_buf_free(&cfg->locked_content);
1144
1468
  git_buf_attach(&cfg->locked_content, git_buf_detach(&buf), len);
1145
1469
  } else {
1146
1470
  git_filebuf_write(&file, git_buf_cstr(&buf), git_buf_len(&buf));
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;
1471
+ result = git_filebuf_commit(&file);
1153
1472
  }
1154
1473
 
1155
1474
  done:
1156
- git__free(section);
1157
- git__free(orig_section);
1158
- git_buf_dispose(&write_data.buffered_comment);
1159
- git_buf_dispose(&buf);
1160
- git_buf_dispose(&contents);
1161
- git_filebuf_cleanup(&file);
1162
- git_config_parser_dispose(&parser);
1163
-
1164
- return error;
1475
+ git_buf_free(&buf);
1476
+ git_buf_free(&contents);
1477
+ git_parse_ctx_clear(&reader.ctx);
1478
+ return result;
1165
1479
  }