rugged 0.17.0.b7 → 0.18.0.b1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (310) hide show
  1. data/LICENSE +1 -1
  2. data/README.md +88 -32
  3. data/ext/rugged/extconf.rb +4 -2
  4. data/ext/rugged/rugged.c +72 -10
  5. data/ext/rugged/rugged.h +14 -10
  6. data/ext/rugged/rugged_blob.c +8 -10
  7. data/ext/rugged/rugged_branch.c +11 -14
  8. data/ext/rugged/rugged_commit.c +31 -24
  9. data/ext/rugged/rugged_config.c +2 -2
  10. data/ext/rugged/rugged_index.c +133 -198
  11. data/ext/rugged/rugged_note.c +372 -0
  12. data/ext/rugged/rugged_object.c +50 -22
  13. data/ext/rugged/rugged_reference.c +122 -130
  14. data/ext/rugged/rugged_remote.c +72 -29
  15. data/ext/rugged/rugged_repo.c +402 -20
  16. data/ext/rugged/rugged_revwalk.c +7 -3
  17. data/ext/rugged/rugged_settings.c +110 -0
  18. data/ext/rugged/rugged_signature.c +23 -7
  19. data/ext/rugged/rugged_tag.c +32 -16
  20. data/ext/rugged/rugged_tree.c +44 -15
  21. data/lib/rugged.rb +1 -0
  22. data/lib/rugged/index.rb +8 -0
  23. data/lib/rugged/remote.rb +13 -0
  24. data/lib/rugged/repository.rb +3 -3
  25. data/lib/rugged/version.rb +1 -1
  26. data/test/blob_test.rb +13 -15
  27. data/test/branch_test.rb +32 -67
  28. data/test/commit_test.rb +50 -12
  29. data/test/config_test.rb +12 -11
  30. data/test/coverage/HEAD.json +1 -1
  31. data/test/coverage/cover.rb +40 -21
  32. data/test/errors_test.rb +34 -0
  33. data/test/fixtures/alternate/objects/14/6ae76773c91e3b1d00cf7a338ec55ae58297e2 +0 -0
  34. data/test/fixtures/alternate/objects/14/9c32d47e99d0a3572ff1e70a2e0051bbf347a9 +0 -0
  35. data/test/fixtures/alternate/objects/14/fb3108588f9421bf764041e5e3ac305eb6277f +0 -0
  36. data/test/fixtures/testrepo.git/logs/refs/notes/commits +1 -0
  37. data/test/fixtures/testrepo.git/objects/44/1034f860c1d5d90e4188d11ae0d325176869a8 +1 -0
  38. data/test/fixtures/testrepo.git/objects/60/d415052a33de2150bf68757f6461df4f563ae4 +0 -0
  39. data/test/fixtures/testrepo.git/objects/68/8a8f4ef7496901d15322972f96e212a9e466cc +1 -0
  40. data/test/fixtures/testrepo.git/objects/94/eca2de348d5f672faf56b0decafa5937e3235e +0 -0
  41. data/test/fixtures/testrepo.git/objects/9b/7384fe1676186192842f5d3e129457b62db9e3 +0 -0
  42. data/test/fixtures/testrepo.git/objects/b7/4713326bc972cc15751ed504dca6f6f3b91f7a +3 -0
  43. data/test/fixtures/testrepo.git/refs/notes/commits +1 -0
  44. data/test/index_test.rb +65 -69
  45. data/test/lib_test.rb +76 -11
  46. data/test/note_test.rb +158 -0
  47. data/test/object_test.rb +8 -11
  48. data/test/reference_test.rb +77 -85
  49. data/test/remote_test.rb +86 -8
  50. data/test/repo_pack_test.rb +9 -7
  51. data/test/repo_reset_test.rb +80 -0
  52. data/test/repo_test.rb +176 -53
  53. data/test/tag_test.rb +44 -7
  54. data/test/test_helper.rb +63 -35
  55. data/test/tree_test.rb +34 -13
  56. data/test/walker_test.rb +14 -14
  57. data/vendor/libgit2/Makefile.embed +1 -1
  58. data/vendor/libgit2/deps/http-parser/http_parser.c +974 -578
  59. data/vendor/libgit2/deps/http-parser/http_parser.h +106 -70
  60. data/vendor/libgit2/deps/regex/regcomp.c +7 -6
  61. data/vendor/libgit2/deps/regex/regex_internal.c +1 -1
  62. data/vendor/libgit2/deps/regex/regex_internal.h +12 -3
  63. data/vendor/libgit2/deps/regex/regexec.c +5 -5
  64. data/vendor/libgit2/include/git2.h +5 -1
  65. data/vendor/libgit2/include/git2/attr.h +4 -2
  66. data/vendor/libgit2/include/git2/blob.h +39 -12
  67. data/vendor/libgit2/include/git2/branch.h +123 -35
  68. data/vendor/libgit2/include/git2/checkout.h +206 -48
  69. data/vendor/libgit2/include/git2/clone.h +72 -27
  70. data/vendor/libgit2/include/git2/commit.h +20 -17
  71. data/vendor/libgit2/include/git2/common.h +67 -1
  72. data/vendor/libgit2/include/git2/config.h +81 -60
  73. data/vendor/libgit2/include/git2/cred_helpers.h +53 -0
  74. data/vendor/libgit2/include/git2/diff.h +459 -150
  75. data/vendor/libgit2/include/git2/errors.h +9 -1
  76. data/vendor/libgit2/include/git2/graph.h +41 -0
  77. data/vendor/libgit2/include/git2/ignore.h +7 -6
  78. data/vendor/libgit2/include/git2/index.h +323 -97
  79. data/vendor/libgit2/include/git2/indexer.h +27 -59
  80. data/vendor/libgit2/include/git2/inttypes.h +4 -0
  81. data/vendor/libgit2/include/git2/merge.h +13 -3
  82. data/vendor/libgit2/include/git2/message.h +14 -8
  83. data/vendor/libgit2/include/git2/net.h +9 -7
  84. data/vendor/libgit2/include/git2/notes.h +88 -29
  85. data/vendor/libgit2/include/git2/object.h +16 -6
  86. data/vendor/libgit2/include/git2/odb.h +80 -17
  87. data/vendor/libgit2/include/git2/odb_backend.h +47 -11
  88. data/vendor/libgit2/include/git2/oid.h +26 -17
  89. data/vendor/libgit2/include/git2/pack.h +62 -8
  90. data/vendor/libgit2/include/git2/push.h +131 -0
  91. data/vendor/libgit2/include/git2/refdb.h +103 -0
  92. data/vendor/libgit2/include/git2/refdb_backend.h +109 -0
  93. data/vendor/libgit2/include/git2/reflog.h +30 -21
  94. data/vendor/libgit2/include/git2/refs.h +215 -193
  95. data/vendor/libgit2/include/git2/refspec.h +22 -2
  96. data/vendor/libgit2/include/git2/remote.h +158 -37
  97. data/vendor/libgit2/include/git2/repository.h +150 -31
  98. data/vendor/libgit2/include/git2/reset.h +43 -9
  99. data/vendor/libgit2/include/git2/revparse.h +48 -4
  100. data/vendor/libgit2/include/git2/revwalk.h +25 -10
  101. data/vendor/libgit2/include/git2/signature.h +20 -12
  102. data/vendor/libgit2/include/git2/stash.h +121 -0
  103. data/vendor/libgit2/include/git2/status.h +122 -53
  104. data/vendor/libgit2/include/git2/strarray.h +17 -11
  105. data/vendor/libgit2/include/git2/submodule.h +42 -7
  106. data/vendor/libgit2/include/git2/tag.h +72 -59
  107. data/vendor/libgit2/include/git2/threads.h +4 -2
  108. data/vendor/libgit2/include/git2/trace.h +68 -0
  109. data/vendor/libgit2/include/git2/transport.h +328 -0
  110. data/vendor/libgit2/include/git2/tree.h +149 -120
  111. data/vendor/libgit2/include/git2/types.h +13 -12
  112. data/vendor/libgit2/include/git2/version.h +3 -3
  113. data/vendor/libgit2/src/amiga/map.c +2 -2
  114. data/vendor/libgit2/src/attr.c +58 -48
  115. data/vendor/libgit2/src/attr.h +4 -18
  116. data/vendor/libgit2/src/attr_file.c +30 -6
  117. data/vendor/libgit2/src/attr_file.h +6 -8
  118. data/vendor/libgit2/src/attrcache.h +24 -0
  119. data/vendor/libgit2/src/blob.c +30 -7
  120. data/vendor/libgit2/src/blob.h +1 -1
  121. data/vendor/libgit2/src/branch.c +361 -68
  122. data/vendor/libgit2/src/branch.h +17 -0
  123. data/vendor/libgit2/src/bswap.h +1 -1
  124. data/vendor/libgit2/src/buf_text.c +291 -0
  125. data/vendor/libgit2/src/buf_text.h +122 -0
  126. data/vendor/libgit2/src/buffer.c +27 -101
  127. data/vendor/libgit2/src/buffer.h +54 -39
  128. data/vendor/libgit2/src/cache.c +15 -6
  129. data/vendor/libgit2/src/cache.h +1 -1
  130. data/vendor/libgit2/src/cc-compat.h +3 -1
  131. data/vendor/libgit2/src/checkout.c +1165 -222
  132. data/vendor/libgit2/src/checkout.h +24 -0
  133. data/vendor/libgit2/src/clone.c +171 -86
  134. data/vendor/libgit2/src/commit.c +44 -45
  135. data/vendor/libgit2/src/commit.h +3 -3
  136. data/vendor/libgit2/src/commit_list.c +194 -0
  137. data/vendor/libgit2/src/commit_list.h +49 -0
  138. data/vendor/libgit2/src/common.h +44 -10
  139. data/vendor/libgit2/src/compress.c +1 -1
  140. data/vendor/libgit2/src/compress.h +1 -1
  141. data/vendor/libgit2/src/config.c +211 -124
  142. data/vendor/libgit2/src/config.h +23 -4
  143. data/vendor/libgit2/src/config_cache.c +2 -2
  144. data/vendor/libgit2/src/config_file.c +129 -53
  145. data/vendor/libgit2/src/config_file.h +10 -8
  146. data/vendor/libgit2/src/crlf.c +66 -67
  147. data/vendor/libgit2/src/date.c +12 -12
  148. data/vendor/libgit2/src/delta-apply.c +14 -1
  149. data/vendor/libgit2/src/delta-apply.h +18 -1
  150. data/vendor/libgit2/src/delta.c +40 -107
  151. data/vendor/libgit2/src/delta.h +19 -17
  152. data/vendor/libgit2/src/diff.c +347 -496
  153. data/vendor/libgit2/src/diff.h +27 -1
  154. data/vendor/libgit2/src/diff_output.c +564 -249
  155. data/vendor/libgit2/src/diff_output.h +15 -8
  156. data/vendor/libgit2/src/diff_tform.c +687 -0
  157. data/vendor/libgit2/src/errors.c +27 -36
  158. data/vendor/libgit2/src/fetch.c +13 -351
  159. data/vendor/libgit2/src/fetch.h +13 -3
  160. data/vendor/libgit2/src/fetchhead.c +295 -0
  161. data/vendor/libgit2/src/fetchhead.h +34 -0
  162. data/vendor/libgit2/src/filebuf.c +42 -15
  163. data/vendor/libgit2/src/filebuf.h +4 -2
  164. data/vendor/libgit2/src/fileops.c +466 -113
  165. data/vendor/libgit2/src/fileops.h +154 -28
  166. data/vendor/libgit2/src/filter.c +3 -75
  167. data/vendor/libgit2/src/filter.h +1 -29
  168. data/vendor/libgit2/src/fnmatch.c +1 -1
  169. data/vendor/libgit2/src/fnmatch.h +1 -1
  170. data/vendor/libgit2/src/global.c +54 -10
  171. data/vendor/libgit2/src/global.h +10 -1
  172. data/vendor/libgit2/src/graph.c +178 -0
  173. data/vendor/libgit2/src/hash.c +25 -52
  174. data/vendor/libgit2/src/hash.h +21 -9
  175. data/vendor/libgit2/src/{sha1/sha1.c → hash/hash_generic.c} +20 -12
  176. data/vendor/libgit2/src/hash/hash_generic.h +24 -0
  177. data/vendor/libgit2/src/hash/hash_openssl.h +45 -0
  178. data/vendor/libgit2/src/hash/hash_win32.c +291 -0
  179. data/vendor/libgit2/src/hash/hash_win32.h +140 -0
  180. data/vendor/libgit2/src/hashsig.c +368 -0
  181. data/vendor/libgit2/src/hashsig.h +72 -0
  182. data/vendor/libgit2/src/ignore.c +22 -15
  183. data/vendor/libgit2/src/ignore.h +6 -1
  184. data/vendor/libgit2/src/index.c +770 -171
  185. data/vendor/libgit2/src/index.h +13 -5
  186. data/vendor/libgit2/src/indexer.c +286 -431
  187. data/vendor/libgit2/src/iterator.c +854 -466
  188. data/vendor/libgit2/src/iterator.h +134 -109
  189. data/vendor/libgit2/src/map.h +1 -1
  190. data/vendor/libgit2/src/merge.c +296 -0
  191. data/vendor/libgit2/src/merge.h +22 -0
  192. data/vendor/libgit2/src/message.c +1 -1
  193. data/vendor/libgit2/src/message.h +1 -1
  194. data/vendor/libgit2/src/mwindow.c +35 -30
  195. data/vendor/libgit2/src/mwindow.h +2 -2
  196. data/vendor/libgit2/src/netops.c +162 -98
  197. data/vendor/libgit2/src/netops.h +50 -15
  198. data/vendor/libgit2/src/notes.c +109 -58
  199. data/vendor/libgit2/src/notes.h +2 -1
  200. data/vendor/libgit2/src/object.c +46 -57
  201. data/vendor/libgit2/src/object.h +1 -8
  202. data/vendor/libgit2/src/odb.c +151 -40
  203. data/vendor/libgit2/src/odb.h +5 -1
  204. data/vendor/libgit2/src/odb_loose.c +4 -5
  205. data/vendor/libgit2/src/odb_pack.c +122 -80
  206. data/vendor/libgit2/src/offmap.h +65 -0
  207. data/vendor/libgit2/src/oid.c +12 -4
  208. data/vendor/libgit2/src/oidmap.h +1 -1
  209. data/vendor/libgit2/src/pack-objects.c +88 -61
  210. data/vendor/libgit2/src/pack-objects.h +8 -8
  211. data/vendor/libgit2/src/pack.c +293 -28
  212. data/vendor/libgit2/src/pack.h +49 -4
  213. data/vendor/libgit2/src/path.c +103 -14
  214. data/vendor/libgit2/src/path.h +23 -7
  215. data/vendor/libgit2/src/pathspec.c +168 -0
  216. data/vendor/libgit2/src/pathspec.h +40 -0
  217. data/vendor/libgit2/src/pool.c +29 -4
  218. data/vendor/libgit2/src/pool.h +8 -1
  219. data/vendor/libgit2/src/posix.c +26 -27
  220. data/vendor/libgit2/src/posix.h +2 -3
  221. data/vendor/libgit2/src/pqueue.c +23 -1
  222. data/vendor/libgit2/src/pqueue.h +23 -1
  223. data/vendor/libgit2/src/push.c +653 -0
  224. data/vendor/libgit2/src/push.h +51 -0
  225. data/vendor/libgit2/src/refdb.c +185 -0
  226. data/vendor/libgit2/src/refdb.h +46 -0
  227. data/vendor/libgit2/src/refdb_fs.c +1024 -0
  228. data/vendor/libgit2/src/refdb_fs.h +15 -0
  229. data/vendor/libgit2/src/reflog.c +77 -45
  230. data/vendor/libgit2/src/reflog.h +1 -3
  231. data/vendor/libgit2/src/refs.c +366 -1326
  232. data/vendor/libgit2/src/refs.h +22 -13
  233. data/vendor/libgit2/src/refspec.c +46 -7
  234. data/vendor/libgit2/src/refspec.h +11 -1
  235. data/vendor/libgit2/src/remote.c +758 -120
  236. data/vendor/libgit2/src/remote.h +10 -5
  237. data/vendor/libgit2/src/repo_template.h +6 -6
  238. data/vendor/libgit2/src/repository.c +315 -96
  239. data/vendor/libgit2/src/repository.h +5 -3
  240. data/vendor/libgit2/src/reset.c +99 -81
  241. data/vendor/libgit2/src/revparse.c +157 -84
  242. data/vendor/libgit2/src/revwalk.c +68 -470
  243. data/vendor/libgit2/src/revwalk.h +44 -0
  244. data/vendor/libgit2/src/sha1_lookup.c +1 -1
  245. data/vendor/libgit2/src/sha1_lookup.h +1 -1
  246. data/vendor/libgit2/src/signature.c +68 -200
  247. data/vendor/libgit2/src/signature.h +1 -1
  248. data/vendor/libgit2/src/stash.c +663 -0
  249. data/vendor/libgit2/src/status.c +101 -79
  250. data/vendor/libgit2/src/strmap.h +1 -1
  251. data/vendor/libgit2/src/submodule.c +67 -51
  252. data/vendor/libgit2/src/submodule.h +1 -1
  253. data/vendor/libgit2/src/tag.c +35 -29
  254. data/vendor/libgit2/src/tag.h +1 -1
  255. data/vendor/libgit2/src/thread-utils.c +1 -1
  256. data/vendor/libgit2/src/thread-utils.h +2 -2
  257. data/vendor/libgit2/src/trace.c +39 -0
  258. data/vendor/libgit2/src/trace.h +56 -0
  259. data/vendor/libgit2/src/transport.c +81 -34
  260. data/vendor/libgit2/src/transports/cred.c +60 -0
  261. data/vendor/libgit2/src/transports/cred_helpers.c +49 -0
  262. data/vendor/libgit2/src/transports/git.c +234 -127
  263. data/vendor/libgit2/src/transports/http.c +761 -433
  264. data/vendor/libgit2/src/transports/local.c +460 -64
  265. data/vendor/libgit2/src/transports/smart.c +345 -0
  266. data/vendor/libgit2/src/transports/smart.h +179 -0
  267. data/vendor/libgit2/src/{pkt.c → transports/smart_pkt.c} +131 -12
  268. data/vendor/libgit2/src/transports/smart_protocol.c +856 -0
  269. data/vendor/libgit2/src/transports/winhttp.c +1136 -0
  270. data/vendor/libgit2/src/tree-cache.c +2 -2
  271. data/vendor/libgit2/src/tree-cache.h +1 -1
  272. data/vendor/libgit2/src/tree.c +239 -166
  273. data/vendor/libgit2/src/tree.h +11 -2
  274. data/vendor/libgit2/src/tsort.c +39 -23
  275. data/vendor/libgit2/src/unix/map.c +1 -1
  276. data/vendor/libgit2/src/unix/posix.h +12 -2
  277. data/vendor/libgit2/src/unix/realpath.c +30 -0
  278. data/vendor/libgit2/src/util.c +250 -13
  279. data/vendor/libgit2/src/util.h +71 -14
  280. data/vendor/libgit2/src/vector.c +123 -60
  281. data/vendor/libgit2/src/vector.h +24 -22
  282. data/vendor/libgit2/src/win32/dir.c +1 -1
  283. data/vendor/libgit2/src/win32/dir.h +1 -1
  284. data/vendor/libgit2/src/win32/error.c +77 -0
  285. data/vendor/libgit2/src/win32/error.h +13 -0
  286. data/vendor/libgit2/src/win32/findfile.c +143 -54
  287. data/vendor/libgit2/src/win32/findfile.h +10 -6
  288. data/vendor/libgit2/src/win32/map.c +1 -1
  289. data/vendor/libgit2/src/win32/mingw-compat.h +1 -1
  290. data/vendor/libgit2/src/win32/msvc-compat.h +10 -1
  291. data/vendor/libgit2/src/win32/posix.h +10 -1
  292. data/vendor/libgit2/src/win32/posix_w32.c +132 -63
  293. data/vendor/libgit2/src/win32/precompiled.c +1 -1
  294. data/vendor/libgit2/src/win32/pthread.c +1 -1
  295. data/vendor/libgit2/src/win32/pthread.h +1 -1
  296. data/vendor/libgit2/src/win32/utf-conv.c +5 -5
  297. data/vendor/libgit2/src/win32/utf-conv.h +3 -3
  298. data/vendor/libgit2/src/win32/version.h +20 -0
  299. metadata +308 -252
  300. data/test/fixtures/testrepo.git/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904 +0 -0
  301. data/test/fixtures/testrepo.git/objects/7f/043268ea43ce18e3540acaabf9e090c91965b0 +0 -0
  302. data/test/fixtures/testrepo.git/objects/a3/e05719b428a2d0ed7a55c4ce53dcc5768c6d5e +0 -0
  303. data/test/index_test.rb~ +0 -218
  304. data/vendor/libgit2/src/pkt.h +0 -91
  305. data/vendor/libgit2/src/ppc/sha1.c +0 -70
  306. data/vendor/libgit2/src/ppc/sha1.h +0 -26
  307. data/vendor/libgit2/src/protocol.c +0 -110
  308. data/vendor/libgit2/src/protocol.h +0 -21
  309. data/vendor/libgit2/src/sha1.h +0 -33
  310. data/vendor/libgit2/src/transport.h +0 -148
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (C) 2009-2012 the libgit2 contributors
2
+ * Copyright (C) the libgit2 contributors. All rights reserved.
3
3
  *
4
4
  * This file is part of libgit2, distributed under the GNU GPL v2 with
5
5
  * a Linking Exception. For full terms see the included COPYING file.
@@ -12,10 +12,11 @@
12
12
  #include "vector.h"
13
13
  #include "repository.h"
14
14
 
15
- #define GIT_CONFIG_FILENAME ".gitconfig"
16
- #define GIT_CONFIG_FILENAME_ALT ".config/git/config"
17
- #define GIT_CONFIG_FILENAME_INREPO "config"
18
15
  #define GIT_CONFIG_FILENAME_SYSTEM "gitconfig"
16
+ #define GIT_CONFIG_FILENAME_GLOBAL ".gitconfig"
17
+ #define GIT_CONFIG_FILENAME_XDG "config"
18
+
19
+ #define GIT_CONFIG_FILENAME_INREPO "config"
19
20
  #define GIT_CONFIG_FILE_MODE 0666
20
21
 
21
22
  struct git_config {
@@ -27,4 +28,22 @@ extern int git_config_find_global_r(git_buf *global_config_path);
27
28
  extern int git_config_find_xdg_r(git_buf *system_config_path);
28
29
  extern int git_config_find_system_r(git_buf *system_config_path);
29
30
 
31
+ extern int git_config_rename_section(
32
+ git_repository *repo,
33
+ const char *old_section_name, /* eg "branch.dummy" */
34
+ const char *new_section_name); /* NULL to drop the old section */
35
+
36
+ /**
37
+ * Create a configuration file backend for ondisk files
38
+ *
39
+ * These are the normal `.gitconfig` files that Core Git
40
+ * processes. Note that you first have to add this file to a
41
+ * configuration object before you can query it for configuration
42
+ * variables.
43
+ *
44
+ * @param out the new backend
45
+ * @param path where the config file is located
46
+ */
47
+ extern int git_config_file__ondisk(struct git_config_backend **out, const char *path);
48
+
30
49
  #endif
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (C) 2009-2012 the libgit2 contributors
2
+ * Copyright (C) the libgit2 contributors. All rights reserved.
3
3
  *
4
4
  * This file is part of libgit2, distributed under the GNU GPL v2 with
5
5
  * a Linking Exception. For full terms see the included COPYING file.
@@ -24,7 +24,7 @@ struct map_data {
24
24
  * core.eol
25
25
  * Sets the line ending type to use in the working directory for
26
26
  * files that have the text property set. Alternatives are lf, crlf
27
- * and native, which uses the platforms native line ending. The default
27
+ * and native, which uses the platform's native line ending. The default
28
28
  * value is native. See gitattributes(5) for more information on
29
29
  * end-of-line conversion.
30
30
  */
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (C) 2009-2012 the libgit2 contributors
2
+ * Copyright (C) the libgit2 contributors. All rights reserved.
3
3
  *
4
4
  * This file is part of libgit2, distributed under the GNU GPL v2 with
5
5
  * a Linking Exception. For full terms see the included COPYING file.
@@ -10,6 +10,7 @@
10
10
  #include "fileops.h"
11
11
  #include "filebuf.h"
12
12
  #include "buffer.h"
13
+ #include "buf_text.h"
13
14
  #include "git2/config.h"
14
15
  #include "git2/types.h"
15
16
  #include "strmap.h"
@@ -64,7 +65,7 @@ typedef struct cvar_t {
64
65
  (iter) = (tmp))
65
66
 
66
67
  typedef struct {
67
- git_config_file parent;
68
+ git_config_backend parent;
68
69
 
69
70
  git_strmap *values;
70
71
 
@@ -75,7 +76,11 @@ typedef struct {
75
76
  int eof;
76
77
  } reader;
77
78
 
78
- char *file_path;
79
+ char *file_path;
80
+ time_t file_mtime;
81
+ size_t file_size;
82
+
83
+ unsigned int level;
79
84
  } diskfile_backend;
80
85
 
81
86
  static int config_parse(diskfile_backend *cfg_file, unsigned int level);
@@ -100,6 +105,29 @@ static void cvar_free(cvar_t *var)
100
105
  git__free(var);
101
106
  }
102
107
 
108
+ int git_config_file_normalize_section(char *start, char *end)
109
+ {
110
+ char *scan;
111
+
112
+ if (start == end)
113
+ return GIT_EINVALIDSPEC;
114
+
115
+ /* Validate and downcase range */
116
+ for (scan = start; *scan; ++scan) {
117
+ if (end && scan >= end)
118
+ break;
119
+ if (isalnum(*scan))
120
+ *scan = tolower(*scan);
121
+ else if (*scan != '-' || scan == start)
122
+ return GIT_EINVALIDSPEC;
123
+ }
124
+
125
+ if (scan == start)
126
+ return GIT_EINVALIDSPEC;
127
+
128
+ return 0;
129
+ }
130
+
103
131
  /* Take something the user gave us and make it nice for our hash function */
104
132
  static int normalize_name(const char *in, char **out)
105
133
  {
@@ -113,19 +141,26 @@ static int normalize_name(const char *in, char **out)
113
141
  fdot = strchr(name, '.');
114
142
  ldot = strrchr(name, '.');
115
143
 
116
- if (fdot == NULL || ldot == NULL) {
117
- git__free(name);
118
- giterr_set(GITERR_CONFIG,
119
- "Invalid variable name: '%s'", in);
120
- return -1;
121
- }
144
+ if (fdot == NULL || fdot == name || ldot == NULL || !ldot[1])
145
+ goto invalid;
146
+
147
+ /* Validate and downcase up to first dot and after last dot */
148
+ if (git_config_file_normalize_section(name, fdot) < 0 ||
149
+ git_config_file_normalize_section(ldot + 1, NULL) < 0)
150
+ goto invalid;
122
151
 
123
- /* Downcase up to the first dot and after the last one */
124
- git__strntolower(name, fdot - name);
125
- git__strtolower(ldot);
152
+ /* If there is a middle range, make sure it doesn't have newlines */
153
+ while (fdot < ldot)
154
+ if (*fdot++ == '\n')
155
+ goto invalid;
126
156
 
127
157
  *out = name;
128
158
  return 0;
159
+
160
+ invalid:
161
+ git__free(name);
162
+ giterr_set(GITERR_CONFIG, "Invalid config item name '%s'", in);
163
+ return GIT_EINVALIDSPEC;
129
164
  }
130
165
 
131
166
  static void free_vars(git_strmap *values)
@@ -145,33 +180,61 @@ static void free_vars(git_strmap *values)
145
180
  git_strmap_free(values);
146
181
  }
147
182
 
148
- static int config_open(git_config_file *cfg, unsigned int level)
183
+ static int config_open(git_config_backend *cfg, unsigned int level)
149
184
  {
150
185
  int res;
151
186
  diskfile_backend *b = (diskfile_backend *)cfg;
152
187
 
188
+ b->level = level;
189
+
153
190
  b->values = git_strmap_alloc();
154
191
  GITERR_CHECK_ALLOC(b->values);
155
192
 
156
193
  git_buf_init(&b->reader.buffer, 0);
157
- res = git_futils_readbuffer(&b->reader.buffer, b->file_path);
194
+ res = git_futils_readbuffer_updated(
195
+ &b->reader.buffer, b->file_path, &b->file_mtime, &b->file_size, NULL);
158
196
 
159
197
  /* It's fine if the file doesn't exist */
160
198
  if (res == GIT_ENOTFOUND)
161
199
  return 0;
162
200
 
163
- if (res < 0 || config_parse(b, level) < 0) {
201
+ if (res < 0 || (res = config_parse(b, level)) < 0) {
164
202
  free_vars(b->values);
165
203
  b->values = NULL;
166
- git_buf_free(&b->reader.buffer);
167
- return -1;
168
204
  }
169
205
 
170
206
  git_buf_free(&b->reader.buffer);
171
- return 0;
207
+ return res;
172
208
  }
173
209
 
174
- static void backend_free(git_config_file *_backend)
210
+ static int config_refresh(git_config_backend *cfg)
211
+ {
212
+ int res, updated = 0;
213
+ diskfile_backend *b = (diskfile_backend *)cfg;
214
+ git_strmap *old_values;
215
+
216
+ res = git_futils_readbuffer_updated(
217
+ &b->reader.buffer, b->file_path, &b->file_mtime, &b->file_size, &updated);
218
+ if (res < 0 || !updated)
219
+ return (res == GIT_ENOTFOUND) ? 0 : res;
220
+
221
+ /* need to reload - store old values and prep for reload */
222
+ old_values = b->values;
223
+ b->values = git_strmap_alloc();
224
+ GITERR_CHECK_ALLOC(b->values);
225
+
226
+ if ((res = config_parse(b, b->level)) < 0) {
227
+ free_vars(b->values);
228
+ b->values = old_values;
229
+ } else {
230
+ free_vars(old_values);
231
+ }
232
+
233
+ git_buf_free(&b->reader.buffer);
234
+ return res;
235
+ }
236
+
237
+ static void backend_free(git_config_backend *_backend)
175
238
  {
176
239
  diskfile_backend *backend = (diskfile_backend *)_backend;
177
240
 
@@ -184,7 +247,7 @@ static void backend_free(git_config_file *_backend)
184
247
  }
185
248
 
186
249
  static int file_foreach(
187
- git_config_file *backend,
250
+ git_config_backend *backend,
188
251
  const char *regexp,
189
252
  int (*fn)(const git_config_entry *, void *),
190
253
  void *data)
@@ -230,7 +293,7 @@ cleanup:
230
293
  return result;
231
294
  }
232
295
 
233
- static int config_set(git_config_file *cfg, const char *name, const char *value)
296
+ static int config_set(git_config_backend *cfg, const char *name, const char *value)
234
297
  {
235
298
  cvar_t *var = NULL, *old_var;
236
299
  diskfile_backend *b = (diskfile_backend *)cfg;
@@ -238,8 +301,8 @@ static int config_set(git_config_file *cfg, const char *name, const char *value)
238
301
  khiter_t pos;
239
302
  int rval, ret;
240
303
 
241
- if (normalize_name(name, &key) < 0)
242
- return -1;
304
+ if ((rval = normalize_name(name, &key)) < 0)
305
+ return rval;
243
306
 
244
307
  /*
245
308
  * Try to find it in the existing values and update it if it
@@ -314,14 +377,15 @@ static int config_set(git_config_file *cfg, const char *name, const char *value)
314
377
  /*
315
378
  * Internal function that actually gets the value in string form
316
379
  */
317
- static int config_get(git_config_file *cfg, const char *name, const git_config_entry **out)
380
+ static int config_get(const git_config_backend *cfg, const char *name, const git_config_entry **out)
318
381
  {
319
382
  diskfile_backend *b = (diskfile_backend *)cfg;
320
383
  char *key;
321
384
  khiter_t pos;
385
+ int error;
322
386
 
323
- if (normalize_name(name, &key) < 0)
324
- return -1;
387
+ if ((error = normalize_name(name, &key)) < 0)
388
+ return error;
325
389
 
326
390
  pos = git_strmap_lookup_index(b->values, key);
327
391
  git__free(key);
@@ -336,7 +400,7 @@ static int config_get(git_config_file *cfg, const char *name, const git_config_e
336
400
  }
337
401
 
338
402
  static int config_get_multivar(
339
- git_config_file *cfg,
403
+ git_config_backend *cfg,
340
404
  const char *name,
341
405
  const char *regex_str,
342
406
  int (*fn)(const git_config_entry *, void *),
@@ -346,9 +410,10 @@ static int config_get_multivar(
346
410
  diskfile_backend *b = (diskfile_backend *)cfg;
347
411
  char *key;
348
412
  khiter_t pos;
413
+ int error;
349
414
 
350
- if (normalize_name(name, &key) < 0)
351
- return -1;
415
+ if ((error = normalize_name(name, &key)) < 0)
416
+ return error;
352
417
 
353
418
  pos = git_strmap_lookup_index(b->values, key);
354
419
  git__free(key);
@@ -399,7 +464,7 @@ static int config_get_multivar(
399
464
  }
400
465
 
401
466
  static int config_set_multivar(
402
- git_config_file *cfg, const char *name, const char *regexp, const char *value)
467
+ git_config_backend *cfg, const char *name, const char *regexp, const char *value)
403
468
  {
404
469
  int replaced = 0;
405
470
  cvar_t *var, *newvar;
@@ -411,8 +476,8 @@ static int config_set_multivar(
411
476
 
412
477
  assert(regexp);
413
478
 
414
- if (normalize_name(name, &key) < 0)
415
- return -1;
479
+ if ((result = normalize_name(name, &key)) < 0)
480
+ return result;
416
481
 
417
482
  pos = git_strmap_lookup_index(b->values, key);
418
483
  if (!git_strmap_valid_index(b->values, pos)) {
@@ -474,7 +539,7 @@ static int config_set_multivar(
474
539
  return result;
475
540
  }
476
541
 
477
- static int config_delete(git_config_file *cfg, const char *name)
542
+ static int config_delete(git_config_backend *cfg, const char *name)
478
543
  {
479
544
  cvar_t *var;
480
545
  diskfile_backend *b = (diskfile_backend *)cfg;
@@ -482,8 +547,8 @@ static int config_delete(git_config_file *cfg, const char *name)
482
547
  int result;
483
548
  khiter_t pos;
484
549
 
485
- if (normalize_name(name, &key) < 0)
486
- return -1;
550
+ if ((result = normalize_name(name, &key)) < 0)
551
+ return result;
487
552
 
488
553
  pos = git_strmap_lookup_index(b->values, key);
489
554
  git__free(key);
@@ -508,14 +573,14 @@ static int config_delete(git_config_file *cfg, const char *name)
508
573
  return result;
509
574
  }
510
575
 
511
- int git_config_file__ondisk(git_config_file **out, const char *path)
576
+ int git_config_file__ondisk(git_config_backend **out, const char *path)
512
577
  {
513
578
  diskfile_backend *backend;
514
579
 
515
- backend = git__malloc(sizeof(diskfile_backend));
580
+ backend = git__calloc(1, sizeof(diskfile_backend));
516
581
  GITERR_CHECK_ALLOC(backend);
517
582
 
518
- memset(backend, 0x0, sizeof(diskfile_backend));
583
+ backend->parent.version = GIT_CONFIG_BACKEND_VERSION;
519
584
 
520
585
  backend->file_path = git__strdup(path);
521
586
  GITERR_CHECK_ALLOC(backend->file_path);
@@ -527,9 +592,10 @@ int git_config_file__ondisk(git_config_file **out, const char *path)
527
592
  backend->parent.set_multivar = config_set_multivar;
528
593
  backend->parent.del = config_delete;
529
594
  backend->parent.foreach = file_foreach;
595
+ backend->parent.refresh = config_refresh;
530
596
  backend->parent.free = backend_free;
531
597
 
532
- *out = (git_config_file *)backend;
598
+ *out = (git_config_backend *)backend;
533
599
 
534
600
  return 0;
535
601
  }
@@ -821,17 +887,14 @@ fail_parse:
821
887
 
822
888
  static int skip_bom(diskfile_backend *cfg)
823
889
  {
824
- static const char utf8_bom[] = { '\xef', '\xbb', '\xbf' };
825
-
826
- if (cfg->reader.buffer.size < sizeof(utf8_bom))
827
- return 0;
890
+ git_bom_t bom;
891
+ int bom_offset = git_buf_text_detect_bom(&bom,
892
+ &cfg->reader.buffer, cfg->reader.read_ptr - cfg->reader.buffer.ptr);
828
893
 
829
- if (memcmp(cfg->reader.read_ptr, utf8_bom, sizeof(utf8_bom)) == 0)
830
- cfg->reader.read_ptr += sizeof(utf8_bom);
894
+ if (bom == GIT_BOM_UTF8)
895
+ cfg->reader.read_ptr += bom_offset;
831
896
 
832
- /* TODO: the reference implementation does pretty stupid
833
- shit with the BoM
834
- */
897
+ /* TODO: reference implementation is pretty stupid with BoM */
835
898
 
836
899
  return 0;
837
900
  }
@@ -891,7 +954,7 @@ static int strip_comments(char *line, int in_quotes)
891
954
  }
892
955
 
893
956
  /* skip any space at the end */
894
- if (git__isspace(ptr[-1])) {
957
+ if (ptr > line && git__isspace(ptr[-1])) {
895
958
  ptr--;
896
959
  }
897
960
  ptr[0] = '\0';
@@ -1187,7 +1250,7 @@ static int config_write(diskfile_backend *cfg, const char *key, const regex_t *p
1187
1250
  }
1188
1251
 
1189
1252
  /* If we are here, there is at least a section line */
1190
- if (*(cfg->reader.buffer.ptr + cfg->reader.buffer.size - 1) != '\n')
1253
+ if (cfg->reader.buffer.size > 0 && *(cfg->reader.buffer.ptr + cfg->reader.buffer.size - 1) != '\n')
1191
1254
  git_filebuf_write(&file, "\n", 1);
1192
1255
 
1193
1256
  git_filebuf_printf(&file, "\t%s = %s\n", name, value);
@@ -1197,8 +1260,12 @@ static int config_write(diskfile_backend *cfg, const char *key, const regex_t *p
1197
1260
  git__free(section);
1198
1261
  git__free(current_section);
1199
1262
 
1263
+ /* refresh stats - if this errors, then commit will error too */
1264
+ (void)git_filebuf_stats(&cfg->file_mtime, &cfg->file_size, &file);
1265
+
1200
1266
  result = git_filebuf_commit(&file, GIT_CONFIG_FILE_MODE);
1201
1267
  git_buf_free(&cfg->reader.buffer);
1268
+
1202
1269
  return result;
1203
1270
 
1204
1271
  rewrite_fail:
@@ -1284,8 +1351,15 @@ out:
1284
1351
 
1285
1352
  static int is_multiline_var(const char *str)
1286
1353
  {
1354
+ int count = 0;
1287
1355
  const char *end = str + strlen(str);
1288
- return (end > str) && (end[-1] == '\\');
1356
+ while (end > str && end[-1] == '\\') {
1357
+ count++;
1358
+ end--;
1359
+ }
1360
+
1361
+ /* An odd number means last backslash wasn't escaped, so it's multiline */
1362
+ return (end > str) && (count & 1);
1289
1363
  }
1290
1364
 
1291
1365
  static int parse_multiline_variable(diskfile_backend *cfg, git_buf *value, int in_quotes)
@@ -1361,7 +1435,7 @@ static int parse_variable(diskfile_backend *cfg, char **var_name, char **var_val
1361
1435
  value_start = var_end + 1;
1362
1436
 
1363
1437
  do var_end--;
1364
- while (git__isspace(*var_end));
1438
+ while (var_end>line && git__isspace(*var_end));
1365
1439
 
1366
1440
  *var_name = git__strndup(line, var_end - line + 1);
1367
1441
  GITERR_CHECK_ALLOC(*var_name);
@@ -1395,8 +1469,10 @@ static int parse_variable(diskfile_backend *cfg, char **var_name, char **var_val
1395
1469
  else if (value_start[0] != '\0') {
1396
1470
  *var_value = fixup_line(value_start, 0);
1397
1471
  GITERR_CHECK_ALLOC(*var_value);
1472
+ } else { /* equals sign but missing rhs */
1473
+ *var_value = git__strdup("");
1474
+ GITERR_CHECK_ALLOC(*var_value);
1398
1475
  }
1399
-
1400
1476
  }
1401
1477
 
1402
1478
  git__free(line);