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.
@@ -17,8 +17,8 @@
17
17
  struct git_commit {
18
18
  git_object object;
19
19
 
20
- git_vector parent_oids;
21
- git_oid tree_oid;
20
+ git_vector parent_ids;
21
+ git_oid tree_id;
22
22
 
23
23
  git_signature *author;
24
24
  git_signature *committer;
@@ -0,0 +1,194 @@
1
+ /*
2
+ * Copyright (C) the libgit2 contributors. All rights reserved.
3
+ *
4
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
5
+ * a Linking Exception. For full terms see the included COPYING file.
6
+ */
7
+
8
+ #include "commit_list.h"
9
+ #include "common.h"
10
+ #include "revwalk.h"
11
+ #include "pool.h"
12
+ #include "odb.h"
13
+
14
+ int git_commit_list_time_cmp(void *a, void *b)
15
+ {
16
+ git_commit_list_node *commit_a = (git_commit_list_node *)a;
17
+ git_commit_list_node *commit_b = (git_commit_list_node *)b;
18
+
19
+ return (commit_a->time < commit_b->time);
20
+ }
21
+
22
+ git_commit_list *git_commit_list_insert(git_commit_list_node *item, git_commit_list **list_p)
23
+ {
24
+ git_commit_list *new_list = git__malloc(sizeof(git_commit_list));
25
+ if (new_list != NULL) {
26
+ new_list->item = item;
27
+ new_list->next = *list_p;
28
+ }
29
+ *list_p = new_list;
30
+ return new_list;
31
+ }
32
+
33
+ git_commit_list *git_commit_list_insert_by_date(git_commit_list_node *item, git_commit_list **list_p)
34
+ {
35
+ git_commit_list **pp = list_p;
36
+ git_commit_list *p;
37
+
38
+ while ((p = *pp) != NULL) {
39
+ if (git_commit_list_time_cmp(p->item, item) < 0)
40
+ break;
41
+
42
+ pp = &p->next;
43
+ }
44
+
45
+ return git_commit_list_insert(item, pp);
46
+ }
47
+
48
+ git_commit_list_node *git_commit_list_alloc_node(git_revwalk *walk)
49
+ {
50
+ return (git_commit_list_node *)git_pool_malloc(&walk->commit_pool, COMMIT_ALLOC);
51
+ }
52
+
53
+ static int commit_error(git_commit_list_node *commit, const char *msg)
54
+ {
55
+ char commit_oid[GIT_OID_HEXSZ + 1];
56
+ git_oid_fmt(commit_oid, &commit->oid);
57
+ commit_oid[GIT_OID_HEXSZ] = '\0';
58
+
59
+ giterr_set(GITERR_ODB, "Failed to parse commit %s - %s", commit_oid, msg);
60
+
61
+ return -1;
62
+ }
63
+
64
+ static git_commit_list_node **alloc_parents(
65
+ git_revwalk *walk, git_commit_list_node *commit, size_t n_parents)
66
+ {
67
+ if (n_parents <= PARENTS_PER_COMMIT)
68
+ return (git_commit_list_node **)((char *)commit + sizeof(git_commit_list_node));
69
+
70
+ return (git_commit_list_node **)git_pool_malloc(
71
+ &walk->commit_pool, (uint32_t)(n_parents * sizeof(git_commit_list_node *)));
72
+ }
73
+
74
+
75
+ void git_commit_list_free(git_commit_list **list_p)
76
+ {
77
+ git_commit_list *list = *list_p;
78
+
79
+ if (list == NULL)
80
+ return;
81
+
82
+ while (list) {
83
+ git_commit_list *temp = list;
84
+ list = temp->next;
85
+ git__free(temp);
86
+ }
87
+
88
+ *list_p = NULL;
89
+ }
90
+
91
+ git_commit_list_node *git_commit_list_pop(git_commit_list **stack)
92
+ {
93
+ git_commit_list *top = *stack;
94
+ git_commit_list_node *item = top ? top->item : NULL;
95
+
96
+ if (top) {
97
+ *stack = top->next;
98
+ git__free(top);
99
+ }
100
+ return item;
101
+ }
102
+
103
+ static int commit_quick_parse(git_revwalk *walk, git_commit_list_node *commit, git_rawobj *raw)
104
+ {
105
+ const size_t parent_len = strlen("parent ") + GIT_OID_HEXSZ + 1;
106
+ unsigned char *buffer = raw->data;
107
+ unsigned char *buffer_end = buffer + raw->len;
108
+ unsigned char *parents_start, *committer_start;
109
+ int i, parents = 0;
110
+ int commit_time;
111
+
112
+ buffer += strlen("tree ") + GIT_OID_HEXSZ + 1;
113
+
114
+ parents_start = buffer;
115
+ while (buffer + parent_len < buffer_end && memcmp(buffer, "parent ", strlen("parent ")) == 0) {
116
+ parents++;
117
+ buffer += parent_len;
118
+ }
119
+
120
+ commit->parents = alloc_parents(walk, commit, parents);
121
+ GITERR_CHECK_ALLOC(commit->parents);
122
+
123
+ buffer = parents_start;
124
+ for (i = 0; i < parents; ++i) {
125
+ git_oid oid;
126
+
127
+ if (git_oid_fromstr(&oid, (char *)buffer + strlen("parent ")) < 0)
128
+ return -1;
129
+
130
+ commit->parents[i] = git_revwalk__commit_lookup(walk, &oid);
131
+ if (commit->parents[i] == NULL)
132
+ return -1;
133
+
134
+ buffer += parent_len;
135
+ }
136
+
137
+ commit->out_degree = (unsigned short)parents;
138
+
139
+ if ((committer_start = buffer = memchr(buffer, '\n', buffer_end - buffer)) == NULL)
140
+ return commit_error(commit, "object is corrupted");
141
+
142
+ buffer++;
143
+
144
+ if ((buffer = memchr(buffer, '\n', buffer_end - buffer)) == NULL)
145
+ return commit_error(commit, "object is corrupted");
146
+
147
+ /* Skip trailing spaces */
148
+ while (buffer > committer_start && git__isspace(*buffer))
149
+ buffer--;
150
+
151
+ /* Seek for the begining of the pack of digits */
152
+ while (buffer > committer_start && git__isdigit(*buffer))
153
+ buffer--;
154
+
155
+ /* Skip potential timezone offset */
156
+ if ((buffer > committer_start) && (*buffer == '+' || *buffer == '-')) {
157
+ buffer--;
158
+
159
+ while (buffer > committer_start && git__isspace(*buffer))
160
+ buffer--;
161
+
162
+ while (buffer > committer_start && git__isdigit(*buffer))
163
+ buffer--;
164
+ }
165
+
166
+ if ((buffer == committer_start) || (git__strtol32(&commit_time, (char *)(buffer + 1), NULL, 10) < 0))
167
+ return commit_error(commit, "cannot parse commit time");
168
+
169
+ commit->time = (time_t)commit_time;
170
+ commit->parsed = 1;
171
+ return 0;
172
+ }
173
+
174
+ int git_commit_list_parse(git_revwalk *walk, git_commit_list_node *commit)
175
+ {
176
+ git_odb_object *obj;
177
+ int error;
178
+
179
+ if (commit->parsed)
180
+ return 0;
181
+
182
+ if ((error = git_odb_read(&obj, walk->odb, &commit->oid)) < 0)
183
+ return error;
184
+
185
+ if (obj->raw.type != GIT_OBJ_COMMIT) {
186
+ giterr_set(GITERR_INVALID, "Object is no commit object");
187
+ error = -1;
188
+ } else
189
+ error = commit_quick_parse(walk, commit, &obj->raw);
190
+
191
+ git_odb_object_free(obj);
192
+ return error;
193
+ }
194
+
@@ -0,0 +1,49 @@
1
+ /*
2
+ * Copyright (C) the libgit2 contributors. All rights reserved.
3
+ *
4
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
5
+ * a Linking Exception. For full terms see the included COPYING file.
6
+ */
7
+ #ifndef INCLUDE_commit_list_h__
8
+ #define INCLUDE_commit_list_h__
9
+
10
+ #include "git2/oid.h"
11
+
12
+ #define PARENT1 (1 << 0)
13
+ #define PARENT2 (1 << 1)
14
+ #define RESULT (1 << 2)
15
+ #define STALE (1 << 3)
16
+
17
+ #define PARENTS_PER_COMMIT 2
18
+ #define COMMIT_ALLOC \
19
+ (sizeof(git_commit_list_node) + PARENTS_PER_COMMIT * sizeof(git_commit_list_node *))
20
+
21
+ typedef struct git_commit_list_node {
22
+ git_oid oid;
23
+ uint32_t time;
24
+ unsigned int seen:1,
25
+ uninteresting:1,
26
+ topo_delay:1,
27
+ parsed:1,
28
+ flags : 4;
29
+
30
+ unsigned short in_degree;
31
+ unsigned short out_degree;
32
+
33
+ struct git_commit_list_node **parents;
34
+ } git_commit_list_node;
35
+
36
+ typedef struct git_commit_list {
37
+ git_commit_list_node *item;
38
+ struct git_commit_list *next;
39
+ } git_commit_list;
40
+
41
+ git_commit_list_node *git_commit_list_alloc_node(git_revwalk *walk);
42
+ int git_commit_list_time_cmp(void *a, void *b);
43
+ void git_commit_list_free(git_commit_list **list_p);
44
+ git_commit_list *git_commit_list_insert(git_commit_list_node *item, git_commit_list **list_p);
45
+ git_commit_list *git_commit_list_insert_by_date(git_commit_list_node *item, git_commit_list **list_p);
46
+ int git_commit_list_parse(git_revwalk *walk, git_commit_list_node *commit);
47
+ git_commit_list_node *git_commit_list_pop(git_commit_list **stack);
48
+
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.
@@ -28,18 +28,20 @@
28
28
  # include <windows.h>
29
29
  # include "win32/msvc-compat.h"
30
30
  # include "win32/mingw-compat.h"
31
+ # include "win32/error.h"
32
+ # include "win32/version.h"
31
33
  # ifdef GIT_THREADS
32
34
  # include "win32/pthread.h"
33
- #endif
34
-
35
- # define snprintf _snprintf
35
+ # endif
36
36
 
37
37
  #else
38
- # include <unistd.h>
39
38
 
39
+ # include <unistd.h>
40
40
  # ifdef GIT_THREADS
41
41
  # include <pthread.h>
42
42
  # endif
43
+ #define GIT_STDLIB_CALL
44
+
43
45
  #endif
44
46
 
45
47
  #include "git2/types.h"
@@ -54,6 +56,12 @@
54
56
  */
55
57
  #define GITERR_CHECK_ALLOC(ptr) if (ptr == NULL) { return -1; }
56
58
 
59
+ /**
60
+ * Check a return value and propogate result if non-zero.
61
+ */
62
+ #define GITERR_CHECK_ERROR(code) \
63
+ do { int _err = (code); if (_err < 0) return _err; } while (0)
64
+
57
65
  /**
58
66
  * Set the error message for this thread, formatting as needed.
59
67
  */
@@ -61,15 +69,41 @@ void giterr_set(int error_class, const char *string, ...);
61
69
 
62
70
  /**
63
71
  * Set the error message for a regex failure, using the internal regex
64
- * error code lookup.
72
+ * error code lookup and return a libgit error code.
65
73
  */
66
- void giterr_set_regex(const regex_t *regex, int error_code);
74
+ int giterr_set_regex(const regex_t *regex, int error_code);
75
+
76
+ /**
77
+ * Check a versioned structure for validity
78
+ */
79
+ GIT_INLINE(int) giterr__check_version(const void *structure, unsigned int expected_max, const char *name)
80
+ {
81
+ unsigned int actual;
82
+
83
+ if (!structure)
84
+ return 0;
85
+
86
+ actual = *(const unsigned int*)structure;
87
+ if (actual > 0 && actual <= expected_max)
88
+ return 0;
89
+
90
+ giterr_set(GITERR_INVALID, "Invalid version %d on %s", actual, name);
91
+ return -1;
92
+ }
93
+ #define GITERR_CHECK_VERSION(S,V,N) if (giterr__check_version(S,V,N) < 0) return -1
94
+
95
+ /**
96
+ * Initialize a structure with a version.
97
+ */
98
+ GIT_INLINE(void) git__init_structure(void *structure, size_t len, unsigned int version)
99
+ {
100
+ memset(structure, 0, len);
101
+ *((int*)structure) = version;
102
+ }
103
+ #define GIT_INIT_STRUCTURE(S,V) git__init_structure(S, sizeof(*S), V)
67
104
 
68
105
  /* NOTE: other giterr functions are in the public errors.h header file */
69
106
 
70
107
  #include "util.h"
71
108
 
72
- typedef struct git_transport git_transport;
73
- typedef struct gitno_buffer gitno_buffer;
74
-
75
109
  #endif /* INCLUDE_common_h__ */
@@ -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.
@@ -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.
@@ -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,8 @@
10
10
  #include "config.h"
11
11
  #include "git2/config.h"
12
12
  #include "vector.h"
13
+ #include "buf_text.h"
14
+ #include "config_file.h"
13
15
  #if GIT_WIN32
14
16
  # include <windows.h>
15
17
  #endif
@@ -19,13 +21,13 @@
19
21
  typedef struct {
20
22
  git_refcount rc;
21
23
 
22
- git_config_file *file;
24
+ git_config_backend *file;
23
25
  unsigned int level;
24
26
  } file_internal;
25
27
 
26
28
  static void file_internal_free(file_internal *internal)
27
29
  {
28
- git_config_file *file;
30
+ git_config_backend *file;
29
31
 
30
32
  file = internal->file;
31
33
  file->free(file);
@@ -34,7 +36,7 @@ static void file_internal_free(file_internal *internal)
34
36
 
35
37
  static void config_free(git_config *cfg)
36
38
  {
37
- unsigned int i;
39
+ size_t i;
38
40
  file_internal *internal;
39
41
 
40
42
  for(i = 0; i < cfg->files.length; ++i){
@@ -87,13 +89,20 @@ int git_config_add_file_ondisk(
87
89
  unsigned int level,
88
90
  int force)
89
91
  {
90
- git_config_file *file = NULL;
92
+ git_config_backend *file = NULL;
91
93
  int res;
92
94
 
95
+ assert(cfg && path);
96
+
97
+ if (!git_path_isfile(path)) {
98
+ giterr_set(GITERR_CONFIG, "Cannot find config file '%s'", path);
99
+ return GIT_ENOTFOUND;
100
+ }
101
+
93
102
  if (git_config_file__ondisk(&file, path) < 0)
94
103
  return -1;
95
104
 
96
- if ((res = git_config_add_file(cfg, file, level, force)) < 0) {
105
+ if ((res = git_config_add_backend(cfg, file, level, force)) < 0) {
97
106
  /*
98
107
  * free manually; the file is not owned by the config
99
108
  * instance yet and will not be freed on cleanup
@@ -105,30 +114,33 @@ int git_config_add_file_ondisk(
105
114
  return 0;
106
115
  }
107
116
 
108
- int git_config_open_ondisk(git_config **cfg, const char *path)
117
+ int git_config_open_ondisk(git_config **out, const char *path)
109
118
  {
110
- if (git_config_new(cfg) < 0)
111
- return -1;
119
+ int error;
120
+ git_config *config;
112
121
 
113
- if (git_config_add_file_ondisk(*cfg, path, GIT_CONFIG_LEVEL_LOCAL, 0) < 0) {
114
- git_config_free(*cfg);
122
+ *out = NULL;
123
+
124
+ if (git_config_new(&config) < 0)
115
125
  return -1;
116
- }
117
126
 
118
- return 0;
127
+ if ((error = git_config_add_file_ondisk(config, path, GIT_CONFIG_LEVEL_LOCAL, 0)) < 0)
128
+ git_config_free(config);
129
+ else
130
+ *out = config;
131
+
132
+ return error;
119
133
  }
120
134
 
121
135
  static int find_internal_file_by_level(
122
136
  file_internal **internal_out,
123
- git_config *cfg,
137
+ const git_config *cfg,
124
138
  int level)
125
139
  {
126
140
  int pos = -1;
127
141
  file_internal *internal;
128
142
  unsigned int i;
129
143
 
130
- assert(cfg->files.length);
131
-
132
144
  /* when passing GIT_CONFIG_HIGHEST_LEVEL, the idea is to get the config file
133
145
  * which has the highest level. As config files are stored in a vector
134
146
  * sorted by decreasing order of level, getting the file at position 0
@@ -214,7 +226,7 @@ static int git_config__add_internal(
214
226
 
215
227
  int git_config_open_level(
216
228
  git_config **cfg_out,
217
- git_config *cfg_parent,
229
+ const git_config *cfg_parent,
218
230
  unsigned int level)
219
231
  {
220
232
  git_config *cfg;
@@ -237,9 +249,9 @@ int git_config_open_level(
237
249
  return 0;
238
250
  }
239
251
 
240
- int git_config_add_file(
252
+ int git_config_add_backend(
241
253
  git_config *cfg,
242
- git_config_file *file,
254
+ git_config_backend *file,
243
255
  unsigned int level,
244
256
  int force)
245
257
  {
@@ -248,6 +260,8 @@ int git_config_add_file(
248
260
 
249
261
  assert(cfg && file);
250
262
 
263
+ GITERR_CHECK_VERSION(file, GIT_CONFIG_BACKEND_VERSION, "git_config_backend");
264
+
251
265
  if ((result = file->open(file, level)) < 0)
252
266
  return result;
253
267
 
@@ -267,39 +281,53 @@ int git_config_add_file(
267
281
  return 0;
268
282
  }
269
283
 
284
+ int git_config_refresh(git_config *cfg)
285
+ {
286
+ int error = 0;
287
+ size_t i;
288
+
289
+ for (i = 0; i < cfg->files.length && !error; ++i) {
290
+ file_internal *internal = git_vector_get(&cfg->files, i);
291
+ git_config_backend *file = internal->file;
292
+ error = file->refresh(file);
293
+ }
294
+
295
+ return error;
296
+ }
297
+
270
298
  /*
271
299
  * Loop over all the variables
272
300
  */
273
301
 
274
302
  int git_config_foreach(
275
- git_config *cfg, int (*fn)(const git_config_entry *, void *), void *data)
303
+ const git_config *cfg, git_config_foreach_cb cb, void *payload)
276
304
  {
277
- return git_config_foreach_match(cfg, NULL, fn, data);
305
+ return git_config_foreach_match(cfg, NULL, cb, payload);
278
306
  }
279
307
 
280
308
  int git_config_foreach_match(
281
- git_config *cfg,
309
+ const git_config *cfg,
282
310
  const char *regexp,
283
- int (*fn)(const git_config_entry *, void *),
284
- void *data)
311
+ git_config_foreach_cb cb,
312
+ void *payload)
285
313
  {
286
314
  int ret = 0;
287
- unsigned int i;
315
+ size_t i;
288
316
  file_internal *internal;
289
- git_config_file *file;
317
+ git_config_backend *file;
290
318
 
291
319
  for (i = 0; i < cfg->files.length && ret == 0; ++i) {
292
320
  internal = git_vector_get(&cfg->files, i);
293
321
  file = internal->file;
294
- ret = file->foreach(file, regexp, fn, data);
322
+ ret = file->foreach(file, regexp, cb, payload);
295
323
  }
296
324
 
297
325
  return ret;
298
326
  }
299
327
 
300
- int git_config_delete(git_config *cfg, const char *name)
328
+ int git_config_delete_entry(git_config *cfg, const char *name)
301
329
  {
302
- git_config_file *file;
330
+ git_config_backend *file;
303
331
  file_internal *internal;
304
332
 
305
333
  internal = git_vector_get(&cfg->files, 0);
@@ -331,9 +359,14 @@ int git_config_set_bool(git_config *cfg, const char *name, int value)
331
359
 
332
360
  int git_config_set_string(git_config *cfg, const char *name, const char *value)
333
361
  {
334
- git_config_file *file;
362
+ git_config_backend *file;
335
363
  file_internal *internal;
336
364
 
365
+ if (!value) {
366
+ giterr_set(GITERR_CONFIG, "The value to set cannot be NULL");
367
+ return -1;
368
+ }
369
+
337
370
  internal = git_vector_get(&cfg->files, 0);
338
371
  file = internal->file;
339
372
 
@@ -345,9 +378,9 @@ int git_config_set_string(git_config *cfg, const char *name, const char *value)
345
378
  ***********/
346
379
  int git_config_get_mapped(
347
380
  int *out,
348
- git_config *cfg,
381
+ const git_config *cfg,
349
382
  const char *name,
350
- git_cvar_map *maps,
383
+ const git_cvar_map *maps,
351
384
  size_t map_n)
352
385
  {
353
386
  const char *value;
@@ -359,7 +392,7 @@ int git_config_get_mapped(
359
392
  return git_config_lookup_map_value(out, maps, map_n, value);
360
393
  }
361
394
 
362
- int git_config_get_int64(int64_t *out, git_config *cfg, const char *name)
395
+ int git_config_get_int64(int64_t *out, const git_config *cfg, const char *name)
363
396
  {
364
397
  const char *value;
365
398
  int ret;
@@ -370,7 +403,7 @@ int git_config_get_int64(int64_t *out, git_config *cfg, const char *name)
370
403
  return git_config_parse_int64(out, value);
371
404
  }
372
405
 
373
- int git_config_get_int32(int32_t *out, git_config *cfg, const char *name)
406
+ int git_config_get_int32(int32_t *out, const git_config *cfg, const char *name)
374
407
  {
375
408
  const char *value;
376
409
  int ret;
@@ -381,38 +414,23 @@ int git_config_get_int32(int32_t *out, git_config *cfg, const char *name)
381
414
  return git_config_parse_int32(out, value);
382
415
  }
383
416
 
384
- int git_config_get_bool(int *out, git_config *cfg, const char *name)
385
- {
386
- const char *value;
387
- int ret;
388
-
389
- if ((ret = git_config_get_string(&value, cfg, name)) < 0)
390
- return ret;
391
-
392
- return git_config_parse_bool(out, value);
393
- }
394
-
395
- static int get_string_at_file(const char **out, git_config_file *file, const char *name)
417
+ static int get_string_at_file(const char **out, const git_config_backend *file, const char *name)
396
418
  {
397
419
  const git_config_entry *entry;
398
420
  int res;
399
421
 
400
- *out = NULL;
401
-
402
422
  res = file->get(file, name, &entry);
403
- if (res != GIT_ENOTFOUND)
423
+ if (!res)
404
424
  *out = entry->value;
405
425
 
406
426
  return res;
407
427
  }
408
428
 
409
- int git_config_get_string(const char **out, git_config *cfg, const char *name)
429
+ static int get_string(const char **out, const git_config *cfg, const char *name)
410
430
  {
411
431
  file_internal *internal;
412
432
  unsigned int i;
413
433
 
414
- assert(cfg->files.length);
415
-
416
434
  git_vector_foreach(&cfg->files, i, internal) {
417
435
  int res = get_string_at_file(out, internal->file, name);
418
436
 
@@ -423,17 +441,38 @@ int git_config_get_string(const char **out, git_config *cfg, const char *name)
423
441
  return GIT_ENOTFOUND;
424
442
  }
425
443
 
426
- int git_config_get_config_entry(const git_config_entry **out, git_config *cfg, const char *name)
444
+ int git_config_get_bool(int *out, const git_config *cfg, const char *name)
445
+ {
446
+ const char *value = NULL;
447
+ int ret;
448
+
449
+ if ((ret = get_string(&value, cfg, name)) < 0)
450
+ return ret;
451
+
452
+ return git_config_parse_bool(out, value);
453
+ }
454
+
455
+ int git_config_get_string(const char **out, const git_config *cfg, const char *name)
456
+ {
457
+ int ret;
458
+ const char *str = NULL;
459
+
460
+ if ((ret = get_string(&str, cfg, name)) < 0)
461
+ return ret;
462
+
463
+ *out = str == NULL ? "" : str;
464
+ return 0;
465
+ }
466
+
467
+ int git_config_get_entry(const git_config_entry **out, const git_config *cfg, const char *name)
427
468
  {
428
469
  file_internal *internal;
429
470
  unsigned int i;
430
471
 
431
- assert(cfg->files.length);
432
-
433
472
  *out = NULL;
434
473
 
435
474
  git_vector_foreach(&cfg->files, i, internal) {
436
- git_config_file *file = internal->file;
475
+ git_config_backend *file = internal->file;
437
476
  int ret = file->get(file, name, out);
438
477
  if (ret != GIT_ENOTFOUND)
439
478
  return ret;
@@ -442,16 +481,14 @@ int git_config_get_config_entry(const git_config_entry **out, git_config *cfg, c
442
481
  return GIT_ENOTFOUND;
443
482
  }
444
483
 
445
- int git_config_get_multivar(git_config *cfg, const char *name, const char *regexp,
446
- int (*fn)(const git_config_entry *entry, void *data), void *data)
484
+ int git_config_get_multivar(const git_config *cfg, const char *name, const char *regexp,
485
+ git_config_foreach_cb cb, void *payload)
447
486
  {
448
487
  file_internal *internal;
449
- git_config_file *file;
488
+ git_config_backend *file;
450
489
  int ret = GIT_ENOTFOUND;
451
490
  size_t i;
452
491
 
453
- assert(cfg->files.length);
454
-
455
492
  /*
456
493
  * This loop runs the "wrong" way 'round because we need to
457
494
  * look at every value from the most general to most specific
@@ -459,7 +496,7 @@ int git_config_get_multivar(git_config *cfg, const char *name, const char *regex
459
496
  for (i = cfg->files.length; i > 0; --i) {
460
497
  internal = git_vector_get(&cfg->files, i - 1);
461
498
  file = internal->file;
462
- ret = file->get_multivar(file, name, regexp, fn, data);
499
+ ret = file->get_multivar(file, name, regexp, cb, payload);
463
500
  if (ret < 0 && ret != GIT_ENOTFOUND)
464
501
  return ret;
465
502
  }
@@ -469,7 +506,7 @@ int git_config_get_multivar(git_config *cfg, const char *name, const char *regex
469
506
 
470
507
  int git_config_set_multivar(git_config *cfg, const char *name, const char *regexp, const char *value)
471
508
  {
472
- git_config_file *file;
509
+ git_config_backend *file;
473
510
  file_internal *internal;
474
511
 
475
512
  internal = git_vector_get(&cfg->files, 0);
@@ -478,62 +515,48 @@ int git_config_set_multivar(git_config *cfg, const char *name, const char *regex
478
515
  return file->set_multivar(file, name, regexp, value);
479
516
  }
480
517
 
481
- int git_config_find_global_r(git_buf *path)
518
+ static int git_config__find_file_to_path(
519
+ char *out, size_t outlen, int (*find)(git_buf *buf))
482
520
  {
483
- int error = git_futils_find_global_file(path, GIT_CONFIG_FILENAME);
521
+ int error = 0;
522
+ git_buf path = GIT_BUF_INIT;
484
523
 
524
+ if ((error = find(&path)) < 0)
525
+ goto done;
526
+
527
+ if (path.size >= outlen) {
528
+ giterr_set(GITERR_NOMEMORY, "Buffer is too short for the path");
529
+ error = GIT_EBUFS;
530
+ goto done;
531
+ }
532
+
533
+ git_buf_copy_cstr(out, outlen, &path);
534
+
535
+ done:
536
+ git_buf_free(&path);
485
537
  return error;
486
538
  }
487
539
 
488
- int git_config_find_xdg_r(git_buf *path)
540
+ int git_config_find_global_r(git_buf *path)
489
541
  {
490
- int error = git_futils_find_global_file(path, GIT_CONFIG_FILENAME_ALT);
491
-
492
- return error;
542
+ return git_futils_find_global_file(path, GIT_CONFIG_FILENAME_GLOBAL);
493
543
  }
494
544
 
495
545
  int git_config_find_global(char *global_config_path, size_t length)
496
546
  {
497
- git_buf path = GIT_BUF_INIT;
498
- int ret = git_config_find_global_r(&path);
499
-
500
- if (ret < 0) {
501
- git_buf_free(&path);
502
- return ret;
503
- }
504
-
505
- if (path.size >= length) {
506
- git_buf_free(&path);
507
- giterr_set(GITERR_NOMEMORY,
508
- "Path is to long to fit on the given buffer");
509
- return -1;
510
- }
547
+ return git_config__find_file_to_path(
548
+ global_config_path, length, git_config_find_global_r);
549
+ }
511
550
 
512
- git_buf_copy_cstr(global_config_path, length, &path);
513
- git_buf_free(&path);
514
- return 0;
551
+ int git_config_find_xdg_r(git_buf *path)
552
+ {
553
+ return git_futils_find_xdg_file(path, GIT_CONFIG_FILENAME_XDG);
515
554
  }
516
555
 
517
556
  int git_config_find_xdg(char *xdg_config_path, size_t length)
518
557
  {
519
- git_buf path = GIT_BUF_INIT;
520
- int ret = git_config_find_xdg_r(&path);
521
-
522
- if (ret < 0) {
523
- git_buf_free(&path);
524
- return ret;
525
- }
526
-
527
- if (path.size >= length) {
528
- git_buf_free(&path);
529
- giterr_set(GITERR_NOMEMORY,
530
- "Path is to long to fit on the given buffer");
531
- return -1;
532
- }
533
-
534
- git_buf_copy_cstr(xdg_config_path, length, &path);
535
- git_buf_free(&path);
536
- return 0;
558
+ return git_config__find_file_to_path(
559
+ xdg_config_path, length, git_config_find_xdg_r);
537
560
  }
538
561
 
539
562
  int git_config_find_system_r(git_buf *path)
@@ -543,24 +566,8 @@ int git_config_find_system_r(git_buf *path)
543
566
 
544
567
  int git_config_find_system(char *system_config_path, size_t length)
545
568
  {
546
- git_buf path = GIT_BUF_INIT;
547
- int ret = git_config_find_system_r(&path);
548
-
549
- if (ret < 0) {
550
- git_buf_free(&path);
551
- return ret;
552
- }
553
-
554
- if (path.size >= length) {
555
- git_buf_free(&path);
556
- giterr_set(GITERR_NOMEMORY,
557
- "Path is to long to fit on the given buffer");
558
- return -1;
559
- }
560
-
561
- git_buf_copy_cstr(system_config_path, length, &path);
562
- git_buf_free(&path);
563
- return 0;
569
+ return git_config__find_file_to_path(
570
+ system_config_path, length, git_config_find_system_r);
564
571
  }
565
572
 
566
573
  int git_config_open_default(git_config **out)
@@ -600,7 +607,7 @@ int git_config_open_default(git_config **out)
600
607
  ***********/
601
608
  int git_config_lookup_map_value(
602
609
  int *out,
603
- git_cvar_map *maps,
610
+ const git_cvar_map *maps,
604
611
  size_t map_n,
605
612
  const char *value)
606
613
  {
@@ -610,7 +617,7 @@ int git_config_lookup_map_value(
610
617
  goto fail_parse;
611
618
 
612
619
  for (i = 0; i < map_n; ++i) {
613
- git_cvar_map *m = maps + i;
620
+ const git_cvar_map *m = maps + i;
614
621
 
615
622
  switch (m->cvar_type) {
616
623
  case GIT_CVAR_FALSE:
@@ -720,3 +727,83 @@ fail_parse:
720
727
  giterr_set(GITERR_CONFIG, "Failed to parse '%s' as a 32-bit integer", value);
721
728
  return -1;
722
729
  }
730
+
731
+ struct rename_data {
732
+ git_config *config;
733
+ git_buf *name;
734
+ size_t old_len;
735
+ int actual_error;
736
+ };
737
+
738
+ static int rename_config_entries_cb(
739
+ const git_config_entry *entry,
740
+ void *payload)
741
+ {
742
+ int error = 0;
743
+ struct rename_data *data = (struct rename_data *)payload;
744
+ size_t base_len = git_buf_len(data->name);
745
+
746
+ if (base_len > 0 &&
747
+ !(error = git_buf_puts(data->name, entry->name + data->old_len)))
748
+ {
749
+ error = git_config_set_string(
750
+ data->config, git_buf_cstr(data->name), entry->value);
751
+
752
+ git_buf_truncate(data->name, base_len);
753
+ }
754
+
755
+ if (!error)
756
+ error = git_config_delete_entry(data->config, entry->name);
757
+
758
+ data->actual_error = error; /* preserve actual error code */
759
+
760
+ return error;
761
+ }
762
+
763
+ int git_config_rename_section(
764
+ git_repository *repo,
765
+ const char *old_section_name,
766
+ const char *new_section_name)
767
+ {
768
+ git_config *config;
769
+ git_buf pattern = GIT_BUF_INIT, replace = GIT_BUF_INIT;
770
+ int error = 0;
771
+ struct rename_data data;
772
+
773
+ git_buf_text_puts_escape_regex(&pattern, old_section_name);
774
+
775
+ if ((error = git_buf_puts(&pattern, "\\..+")) < 0)
776
+ goto cleanup;
777
+
778
+ if ((error = git_repository_config__weakptr(&config, repo)) < 0)
779
+ goto cleanup;
780
+
781
+ data.config = config;
782
+ data.name = &replace;
783
+ data.old_len = strlen(old_section_name) + 1;
784
+ data.actual_error = 0;
785
+
786
+ if ((error = git_buf_join(&replace, '.', new_section_name, "")) < 0)
787
+ goto cleanup;
788
+
789
+ if (new_section_name != NULL &&
790
+ (error = git_config_file_normalize_section(
791
+ replace.ptr, strchr(replace.ptr, '.'))) < 0)
792
+ {
793
+ giterr_set(
794
+ GITERR_CONFIG, "Invalid config section '%s'", new_section_name);
795
+ goto cleanup;
796
+ }
797
+
798
+ error = git_config_foreach_match(
799
+ config, git_buf_cstr(&pattern), rename_config_entries_cb, &data);
800
+
801
+ if (error == GIT_EUSER)
802
+ error = data.actual_error;
803
+
804
+ cleanup:
805
+ git_buf_free(&pattern);
806
+ git_buf_free(&replace);
807
+
808
+ return error;
809
+ }