rugged 0.19.0 → 0.28.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (668) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +1 -1
  3. data/README.md +184 -33
  4. data/ext/rugged/extconf.rb +111 -28
  5. data/ext/rugged/rugged.c +327 -89
  6. data/ext/rugged/rugged.h +64 -28
  7. data/ext/rugged/rugged_allocator.c +89 -0
  8. data/ext/rugged/rugged_backend.c +17 -0
  9. data/ext/rugged/rugged_blame.c +278 -0
  10. data/ext/rugged/rugged_blob.c +301 -75
  11. data/ext/rugged/rugged_branch.c +92 -242
  12. data/ext/rugged/rugged_branch_collection.c +388 -0
  13. data/ext/rugged/rugged_commit.c +575 -79
  14. data/ext/rugged/rugged_config.c +129 -36
  15. data/ext/rugged/rugged_cred.c +131 -0
  16. data/ext/rugged/rugged_diff.c +291 -122
  17. data/ext/rugged/rugged_diff_delta.c +16 -22
  18. data/ext/rugged/rugged_diff_hunk.c +35 -51
  19. data/ext/rugged/rugged_diff_line.c +23 -36
  20. data/ext/rugged/rugged_index.c +289 -152
  21. data/ext/rugged/rugged_note.c +50 -60
  22. data/ext/rugged/rugged_object.c +13 -30
  23. data/ext/rugged/rugged_patch.c +400 -0
  24. data/ext/rugged/rugged_rebase.c +397 -0
  25. data/ext/rugged/rugged_reference.c +76 -346
  26. data/ext/rugged/rugged_reference_collection.c +423 -0
  27. data/ext/rugged/rugged_remote.c +438 -461
  28. data/ext/rugged/rugged_remote_collection.c +435 -0
  29. data/ext/rugged/rugged_repo.c +1548 -365
  30. data/ext/rugged/rugged_revwalk.c +378 -99
  31. data/ext/rugged/rugged_settings.c +86 -23
  32. data/ext/rugged/rugged_signature.c +47 -37
  33. data/ext/rugged/rugged_submodule.c +835 -0
  34. data/ext/rugged/rugged_submodule_collection.c +366 -0
  35. data/ext/rugged/rugged_tag.c +88 -210
  36. data/ext/rugged/rugged_tag_collection.c +326 -0
  37. data/ext/rugged/rugged_tree.c +460 -217
  38. data/lib/rugged/attributes.rb +46 -0
  39. data/lib/rugged/blob.rb +33 -0
  40. data/lib/rugged/branch.rb +12 -16
  41. data/lib/rugged/commit.rb +9 -0
  42. data/lib/rugged/console.rb +5 -0
  43. data/lib/rugged/credentials.rb +48 -0
  44. data/lib/rugged/diff/delta.rb +6 -2
  45. data/lib/rugged/diff/hunk.rb +9 -9
  46. data/lib/rugged/diff/line.rb +28 -5
  47. data/lib/rugged/diff.rb +7 -1
  48. data/lib/rugged/index.rb +120 -0
  49. data/lib/rugged/object.rb +5 -0
  50. data/lib/rugged/patch.rb +41 -0
  51. data/lib/rugged/reference.rb +6 -3
  52. data/lib/rugged/remote.rb +5 -9
  53. data/lib/rugged/repository.rb +126 -14
  54. data/lib/rugged/submodule_collection.rb +53 -0
  55. data/lib/rugged/tag.rb +45 -16
  56. data/lib/rugged/tree.rb +163 -1
  57. data/lib/rugged/version.rb +6 -1
  58. data/lib/rugged/walker.rb +5 -0
  59. data/lib/rugged.rb +16 -1
  60. data/vendor/libgit2/AUTHORS +77 -0
  61. data/vendor/libgit2/CMakeLists.txt +317 -0
  62. data/vendor/libgit2/COPYING +993 -0
  63. data/vendor/libgit2/cmake/Modules/AddCFlagIfSupported.cmake +30 -0
  64. data/vendor/libgit2/cmake/Modules/CheckPrototypeDefinition.c.in +29 -0
  65. data/vendor/libgit2/cmake/Modules/CheckPrototypeDefinition.cmake +96 -0
  66. data/vendor/libgit2/cmake/Modules/EnableWarnings.cmake +11 -0
  67. data/vendor/libgit2/cmake/Modules/FindCoreFoundation.cmake +26 -0
  68. data/vendor/libgit2/cmake/Modules/FindGSSAPI.cmake +324 -0
  69. data/vendor/libgit2/cmake/Modules/FindHTTP_Parser.cmake +39 -0
  70. data/vendor/libgit2/cmake/Modules/FindIconv.cmake +45 -0
  71. data/vendor/libgit2/cmake/Modules/FindPkgLibraries.cmake +28 -0
  72. data/vendor/libgit2/cmake/Modules/FindSecurity.cmake +28 -0
  73. data/vendor/libgit2/cmake/Modules/FindStatNsec.cmake +20 -0
  74. data/vendor/libgit2/cmake/Modules/FindmbedTLS.cmake +93 -0
  75. data/vendor/libgit2/cmake/Modules/IdeSplitSources.cmake +22 -0
  76. data/vendor/libgit2/deps/http-parser/CMakeLists.txt +5 -0
  77. data/vendor/libgit2/deps/http-parser/COPYING +23 -0
  78. data/vendor/libgit2/deps/http-parser/http_parser.c +5 -2
  79. data/vendor/libgit2/deps/http-parser/http_parser.h +2 -0
  80. data/vendor/libgit2/deps/regex/CMakeLists.txt +2 -0
  81. data/vendor/libgit2/deps/regex/COPYING +502 -0
  82. data/vendor/libgit2/deps/regex/regex.c +10 -3
  83. data/vendor/libgit2/deps/winhttp/CMakeLists.txt +26 -0
  84. data/vendor/libgit2/deps/winhttp/COPYING.GPL +993 -0
  85. data/vendor/libgit2/deps/winhttp/COPYING.LGPL +502 -0
  86. data/vendor/libgit2/deps/winhttp/urlmon.h +45 -0
  87. data/vendor/libgit2/deps/winhttp/winhttp.def +29 -0
  88. data/vendor/libgit2/deps/winhttp/winhttp.h +594 -0
  89. data/vendor/libgit2/deps/winhttp/winhttp64.def +29 -0
  90. data/vendor/libgit2/deps/zlib/CMakeLists.txt +5 -0
  91. data/vendor/libgit2/deps/zlib/COPYING +27 -0
  92. data/vendor/libgit2/deps/zlib/adler32.c +51 -34
  93. data/vendor/libgit2/deps/zlib/crc32.c +61 -61
  94. data/vendor/libgit2/deps/zlib/crc32.h +1 -1
  95. data/vendor/libgit2/deps/zlib/deflate.c +681 -352
  96. data/vendor/libgit2/deps/zlib/deflate.h +25 -18
  97. data/vendor/libgit2/deps/zlib/gzguts.h +218 -0
  98. data/vendor/libgit2/deps/zlib/infback.c +640 -0
  99. data/vendor/libgit2/deps/zlib/inffast.c +36 -53
  100. data/vendor/libgit2/deps/zlib/inffixed.h +3 -3
  101. data/vendor/libgit2/deps/zlib/inflate.c +167 -86
  102. data/vendor/libgit2/deps/zlib/inflate.h +7 -4
  103. data/vendor/libgit2/deps/zlib/inftrees.c +24 -50
  104. data/vendor/libgit2/deps/zlib/trees.c +55 -96
  105. data/vendor/libgit2/deps/zlib/zconf.h +499 -19
  106. data/vendor/libgit2/deps/zlib/zlib.h +526 -227
  107. data/vendor/libgit2/deps/zlib/zutil.c +39 -32
  108. data/vendor/libgit2/deps/zlib/zutil.h +75 -78
  109. data/vendor/libgit2/include/git2/annotated_commit.h +125 -0
  110. data/vendor/libgit2/include/git2/apply.h +129 -0
  111. data/vendor/libgit2/include/git2/attr.h +36 -21
  112. data/vendor/libgit2/include/git2/blame.h +229 -0
  113. data/vendor/libgit2/include/git2/blob.h +81 -44
  114. data/vendor/libgit2/include/git2/branch.h +81 -42
  115. data/vendor/libgit2/include/git2/buffer.h +128 -0
  116. data/vendor/libgit2/include/git2/checkout.h +141 -67
  117. data/vendor/libgit2/include/git2/cherrypick.h +92 -0
  118. data/vendor/libgit2/include/git2/clone.h +157 -58
  119. data/vendor/libgit2/include/git2/commit.h +231 -12
  120. data/vendor/libgit2/include/git2/common.h +216 -30
  121. data/vendor/libgit2/include/git2/config.h +274 -48
  122. data/vendor/libgit2/include/git2/cred_helpers.h +4 -4
  123. data/vendor/libgit2/include/git2/deprecated.h +253 -0
  124. data/vendor/libgit2/include/git2/describe.h +189 -0
  125. data/vendor/libgit2/include/git2/diff.h +985 -575
  126. data/vendor/libgit2/include/git2/errors.h +93 -52
  127. data/vendor/libgit2/include/git2/filter.h +217 -0
  128. data/vendor/libgit2/include/git2/global.h +44 -0
  129. data/vendor/libgit2/include/git2/graph.h +17 -0
  130. data/vendor/libgit2/include/git2/ignore.h +2 -2
  131. data/vendor/libgit2/include/git2/index.h +269 -94
  132. data/vendor/libgit2/include/git2/indexer.h +44 -12
  133. data/vendor/libgit2/include/git2/mailmap.h +115 -0
  134. data/vendor/libgit2/include/git2/merge.h +501 -64
  135. data/vendor/libgit2/include/git2/message.h +52 -17
  136. data/vendor/libgit2/include/git2/net.h +11 -5
  137. data/vendor/libgit2/include/git2/notes.h +120 -16
  138. data/vendor/libgit2/include/git2/object.h +62 -23
  139. data/vendor/libgit2/include/git2/odb.h +140 -24
  140. data/vendor/libgit2/include/git2/odb_backend.h +56 -12
  141. data/vendor/libgit2/include/git2/oid.h +17 -18
  142. data/vendor/libgit2/include/git2/oidarray.h +40 -0
  143. data/vendor/libgit2/include/git2/pack.h +86 -7
  144. data/vendor/libgit2/include/git2/patch.h +274 -0
  145. data/vendor/libgit2/include/git2/pathspec.h +280 -0
  146. data/vendor/libgit2/include/git2/proxy.h +96 -0
  147. data/vendor/libgit2/include/git2/rebase.h +323 -0
  148. data/vendor/libgit2/include/git2/reflog.h +12 -9
  149. data/vendor/libgit2/include/git2/refs.h +241 -46
  150. data/vendor/libgit2/include/git2/refspec.h +20 -4
  151. data/vendor/libgit2/include/git2/remote.h +636 -209
  152. data/vendor/libgit2/include/git2/repository.h +267 -57
  153. data/vendor/libgit2/include/git2/reset.h +36 -6
  154. data/vendor/libgit2/include/git2/revert.h +91 -0
  155. data/vendor/libgit2/include/git2/revparse.h +27 -16
  156. data/vendor/libgit2/include/git2/revwalk.h +78 -35
  157. data/vendor/libgit2/include/git2/signature.h +32 -5
  158. data/vendor/libgit2/include/git2/stash.h +160 -21
  159. data/vendor/libgit2/include/git2/status.h +92 -30
  160. data/vendor/libgit2/include/git2/submodule.h +226 -133
  161. data/vendor/libgit2/include/git2/sys/alloc.h +101 -0
  162. data/vendor/libgit2/include/git2/sys/commit.h +38 -4
  163. data/vendor/libgit2/include/git2/sys/config.h +68 -9
  164. data/vendor/libgit2/include/git2/sys/diff.h +94 -0
  165. data/vendor/libgit2/include/git2/sys/filter.h +332 -0
  166. data/vendor/libgit2/include/git2/sys/hashsig.h +106 -0
  167. data/vendor/libgit2/include/git2/sys/index.h +6 -5
  168. data/vendor/libgit2/include/git2/sys/mempack.h +86 -0
  169. data/vendor/libgit2/include/git2/sys/merge.h +182 -0
  170. data/vendor/libgit2/include/git2/sys/odb_backend.h +66 -28
  171. data/vendor/libgit2/include/git2/sys/openssl.h +38 -0
  172. data/vendor/libgit2/include/git2/sys/path.h +64 -0
  173. data/vendor/libgit2/include/git2/sys/refdb_backend.h +79 -19
  174. data/vendor/libgit2/include/git2/sys/reflog.h +21 -0
  175. data/vendor/libgit2/include/git2/sys/refs.h +13 -2
  176. data/vendor/libgit2/include/git2/sys/repository.h +64 -1
  177. data/vendor/libgit2/include/git2/sys/stream.h +138 -0
  178. data/vendor/libgit2/include/git2/sys/time.h +31 -0
  179. data/vendor/libgit2/include/git2/sys/transport.h +439 -0
  180. data/vendor/libgit2/include/git2/tag.h +11 -2
  181. data/vendor/libgit2/include/git2/trace.h +1 -1
  182. data/vendor/libgit2/include/git2/transaction.h +121 -0
  183. data/vendor/libgit2/include/git2/transport.h +261 -292
  184. data/vendor/libgit2/include/git2/tree.h +111 -21
  185. data/vendor/libgit2/include/git2/types.h +244 -32
  186. data/vendor/libgit2/include/git2/version.h +5 -2
  187. data/vendor/libgit2/include/git2/worktree.h +255 -0
  188. data/vendor/libgit2/include/git2.h +50 -40
  189. data/vendor/libgit2/libgit2.pc.in +13 -0
  190. data/vendor/libgit2/src/CMakeLists.txt +525 -0
  191. data/vendor/libgit2/src/alloc.c +55 -0
  192. data/vendor/libgit2/src/alloc.h +40 -0
  193. data/vendor/libgit2/src/annotated_commit.c +228 -0
  194. data/vendor/libgit2/src/annotated_commit.h +52 -0
  195. data/vendor/libgit2/src/apply.c +855 -0
  196. data/vendor/libgit2/src/apply.h +25 -0
  197. data/vendor/libgit2/src/array.h +74 -16
  198. data/vendor/libgit2/src/attr.c +239 -408
  199. data/vendor/libgit2/src/attr.h +3 -33
  200. data/vendor/libgit2/src/attr_file.c +424 -156
  201. data/vendor/libgit2/src/attr_file.h +95 -23
  202. data/vendor/libgit2/src/attrcache.c +469 -0
  203. data/vendor/libgit2/src/attrcache.h +37 -5
  204. data/vendor/libgit2/src/bitvec.h +75 -0
  205. data/vendor/libgit2/src/blame.c +532 -0
  206. data/vendor/libgit2/src/blame.h +95 -0
  207. data/vendor/libgit2/src/blame_git.c +668 -0
  208. data/vendor/libgit2/src/blame_git.h +22 -0
  209. data/vendor/libgit2/src/blob.c +233 -129
  210. data/vendor/libgit2/src/blob.h +29 -1
  211. data/vendor/libgit2/src/branch.c +295 -197
  212. data/vendor/libgit2/src/branch.h +2 -0
  213. data/vendor/libgit2/src/buf_text.c +52 -27
  214. data/vendor/libgit2/src/buf_text.h +7 -7
  215. data/vendor/libgit2/src/buffer.c +609 -52
  216. data/vendor/libgit2/src/buffer.h +68 -23
  217. data/vendor/libgit2/src/cache.c +48 -51
  218. data/vendor/libgit2/src/cache.h +6 -4
  219. data/vendor/libgit2/src/cc-compat.h +35 -7
  220. data/vendor/libgit2/src/checkout.c +1827 -483
  221. data/vendor/libgit2/src/checkout.h +4 -1
  222. data/vendor/libgit2/src/cherrypick.c +230 -0
  223. data/vendor/libgit2/src/clone.c +338 -258
  224. data/vendor/libgit2/src/{compress.h → clone.h} +5 -5
  225. data/vendor/libgit2/src/commit.c +711 -124
  226. data/vendor/libgit2/src/commit.h +10 -3
  227. data/vendor/libgit2/src/commit_list.c +21 -14
  228. data/vendor/libgit2/src/commit_list.h +9 -3
  229. data/vendor/libgit2/src/common.h +153 -13
  230. data/vendor/libgit2/src/config.c +871 -242
  231. data/vendor/libgit2/src/config.h +58 -14
  232. data/vendor/libgit2/src/config_backend.h +84 -0
  233. data/vendor/libgit2/src/config_cache.c +44 -18
  234. data/vendor/libgit2/src/config_entries.c +259 -0
  235. data/vendor/libgit2/src/config_entries.h +23 -0
  236. data/vendor/libgit2/src/config_file.c +837 -1113
  237. data/vendor/libgit2/src/config_mem.c +224 -0
  238. data/vendor/libgit2/src/config_parse.c +558 -0
  239. data/vendor/libgit2/src/config_parse.h +64 -0
  240. data/vendor/libgit2/src/crlf.c +290 -195
  241. data/vendor/libgit2/src/date.c +35 -7
  242. data/vendor/libgit2/src/delta.c +275 -71
  243. data/vendor/libgit2/src/delta.h +80 -58
  244. data/vendor/libgit2/src/describe.c +893 -0
  245. data/vendor/libgit2/src/diff.c +330 -1128
  246. data/vendor/libgit2/src/diff.h +25 -67
  247. data/vendor/libgit2/src/diff_driver.c +225 -109
  248. data/vendor/libgit2/src/diff_driver.h +5 -2
  249. data/vendor/libgit2/src/diff_file.c +128 -103
  250. data/vendor/libgit2/src/diff_file.h +17 -12
  251. data/vendor/libgit2/src/diff_generate.c +1622 -0
  252. data/vendor/libgit2/src/diff_generate.h +128 -0
  253. data/vendor/libgit2/src/diff_parse.c +108 -0
  254. data/vendor/libgit2/src/diff_parse.h +20 -0
  255. data/vendor/libgit2/src/diff_print.c +578 -218
  256. data/vendor/libgit2/src/diff_stats.c +362 -0
  257. data/vendor/libgit2/src/diff_tform.c +429 -257
  258. data/vendor/libgit2/src/diff_tform.h +25 -0
  259. data/vendor/libgit2/src/diff_xdiff.c +143 -46
  260. data/vendor/libgit2/src/diff_xdiff.h +12 -5
  261. data/vendor/libgit2/src/errors.c +150 -34
  262. data/vendor/libgit2/src/features.h.in +37 -0
  263. data/vendor/libgit2/src/fetch.c +69 -46
  264. data/vendor/libgit2/src/fetch.h +6 -12
  265. data/vendor/libgit2/src/fetchhead.c +40 -33
  266. data/vendor/libgit2/src/fetchhead.h +5 -4
  267. data/vendor/libgit2/src/filebuf.c +163 -61
  268. data/vendor/libgit2/src/filebuf.h +13 -7
  269. data/vendor/libgit2/src/fileops.c +549 -407
  270. data/vendor/libgit2/src/fileops.h +97 -106
  271. data/vendor/libgit2/src/filter.c +989 -46
  272. data/vendor/libgit2/src/filter.h +21 -70
  273. data/vendor/libgit2/src/fnmatch.c +67 -11
  274. data/vendor/libgit2/src/fnmatch.h +27 -7
  275. data/vendor/libgit2/src/global.c +257 -63
  276. data/vendor/libgit2/src/global.h +19 -0
  277. data/vendor/libgit2/src/graph.c +39 -23
  278. data/vendor/libgit2/src/hash/hash_collisiondetect.h +51 -0
  279. data/vendor/libgit2/src/hash/hash_common_crypto.h +61 -0
  280. data/vendor/libgit2/src/hash/hash_generic.c +3 -3
  281. data/vendor/libgit2/src/hash/hash_generic.h +10 -5
  282. data/vendor/libgit2/src/hash/hash_mbedtls.c +38 -0
  283. data/vendor/libgit2/src/hash/hash_mbedtls.h +24 -0
  284. data/vendor/libgit2/src/hash/hash_openssl.h +26 -8
  285. data/vendor/libgit2/src/hash/hash_win32.c +71 -43
  286. data/vendor/libgit2/src/hash/hash_win32.h +4 -3
  287. data/vendor/libgit2/src/hash/sha1dc/sha1.c +1900 -0
  288. data/vendor/libgit2/src/hash/sha1dc/sha1.h +110 -0
  289. data/vendor/libgit2/src/hash/sha1dc/ubc_check.c +372 -0
  290. data/vendor/libgit2/src/hash/sha1dc/ubc_check.h +52 -0
  291. data/vendor/libgit2/src/hash.c +0 -1
  292. data/vendor/libgit2/src/hash.h +13 -6
  293. data/vendor/libgit2/src/hashsig.c +121 -126
  294. data/vendor/libgit2/src/ident.c +129 -0
  295. data/vendor/libgit2/src/idxmap.c +153 -0
  296. data/vendor/libgit2/src/idxmap.h +41 -0
  297. data/vendor/libgit2/src/ignore.c +362 -123
  298. data/vendor/libgit2/src/ignore.h +16 -4
  299. data/vendor/libgit2/src/index.c +2131 -692
  300. data/vendor/libgit2/src/index.h +138 -6
  301. data/vendor/libgit2/src/indexer.c +866 -266
  302. data/vendor/libgit2/src/indexer.h +16 -0
  303. data/vendor/libgit2/src/integer.h +106 -0
  304. data/vendor/libgit2/src/iterator.c +1888 -967
  305. data/vendor/libgit2/src/iterator.h +130 -67
  306. data/vendor/libgit2/src/khash.h +43 -29
  307. data/vendor/libgit2/src/mailmap.c +485 -0
  308. data/vendor/libgit2/src/mailmap.h +35 -0
  309. data/vendor/libgit2/src/map.h +1 -1
  310. data/vendor/libgit2/src/merge.c +1679 -479
  311. data/vendor/libgit2/src/merge.h +89 -22
  312. data/vendor/libgit2/src/merge_driver.c +426 -0
  313. data/vendor/libgit2/src/merge_driver.h +62 -0
  314. data/vendor/libgit2/src/merge_file.c +238 -101
  315. data/vendor/libgit2/src/message.c +4 -28
  316. data/vendor/libgit2/src/message.h +3 -1
  317. data/vendor/libgit2/src/mwindow.c +123 -15
  318. data/vendor/libgit2/src/mwindow.h +10 -1
  319. data/vendor/libgit2/src/netops.c +178 -499
  320. data/vendor/libgit2/src/netops.h +51 -27
  321. data/vendor/libgit2/src/notes.c +251 -94
  322. data/vendor/libgit2/src/notes.h +5 -2
  323. data/vendor/libgit2/src/object.c +253 -67
  324. data/vendor/libgit2/src/object.h +40 -2
  325. data/vendor/libgit2/src/object_api.c +30 -11
  326. data/vendor/libgit2/src/odb.c +765 -201
  327. data/vendor/libgit2/src/odb.h +40 -8
  328. data/vendor/libgit2/src/odb_loose.c +560 -346
  329. data/vendor/libgit2/src/odb_mempack.c +185 -0
  330. data/vendor/libgit2/src/odb_pack.c +117 -73
  331. data/vendor/libgit2/src/offmap.c +113 -0
  332. data/vendor/libgit2/src/offmap.h +32 -42
  333. data/vendor/libgit2/src/oid.c +45 -25
  334. data/vendor/libgit2/src/oid.h +26 -8
  335. data/vendor/libgit2/src/oidarray.c +34 -0
  336. data/vendor/libgit2/src/oidarray.h +20 -0
  337. data/vendor/libgit2/src/oidmap.c +125 -0
  338. data/vendor/libgit2/src/oidmap.h +30 -17
  339. data/vendor/libgit2/src/pack-objects.c +688 -265
  340. data/vendor/libgit2/src/pack-objects.h +27 -13
  341. data/vendor/libgit2/src/pack.c +418 -202
  342. data/vendor/libgit2/src/pack.h +25 -16
  343. data/vendor/libgit2/src/parse.c +124 -0
  344. data/vendor/libgit2/src/parse.h +61 -0
  345. data/vendor/libgit2/src/patch.c +223 -0
  346. data/vendor/libgit2/src/patch.h +68 -0
  347. data/vendor/libgit2/src/patch_generate.c +901 -0
  348. data/vendor/libgit2/src/patch_generate.h +69 -0
  349. data/vendor/libgit2/src/patch_parse.c +1136 -0
  350. data/vendor/libgit2/src/patch_parse.h +51 -0
  351. data/vendor/libgit2/src/path.c +1247 -241
  352. data/vendor/libgit2/src/path.h +353 -57
  353. data/vendor/libgit2/src/pathspec.c +586 -58
  354. data/vendor/libgit2/src/pathspec.h +37 -15
  355. data/vendor/libgit2/src/pool.c +134 -221
  356. data/vendor/libgit2/src/pool.h +38 -50
  357. data/vendor/libgit2/src/posix.c +76 -10
  358. data/vendor/libgit2/src/posix.h +74 -32
  359. data/vendor/libgit2/src/pqueue.c +79 -117
  360. data/vendor/libgit2/src/pqueue.h +38 -82
  361. data/vendor/libgit2/src/proxy.c +39 -0
  362. data/vendor/libgit2/src/proxy.h +17 -0
  363. data/vendor/libgit2/src/push.c +178 -279
  364. data/vendor/libgit2/src/push.h +93 -4
  365. data/vendor/libgit2/src/reader.c +265 -0
  366. data/vendor/libgit2/src/reader.h +107 -0
  367. data/vendor/libgit2/src/rebase.c +1364 -0
  368. data/vendor/libgit2/src/refdb.c +74 -19
  369. data/vendor/libgit2/src/refdb.h +16 -3
  370. data/vendor/libgit2/src/refdb_fs.c +1472 -603
  371. data/vendor/libgit2/src/refdb_fs.h +4 -0
  372. data/vendor/libgit2/src/reflog.c +40 -330
  373. data/vendor/libgit2/src/reflog.h +8 -2
  374. data/vendor/libgit2/src/refs.c +641 -225
  375. data/vendor/libgit2/src/refs.h +53 -6
  376. data/vendor/libgit2/src/refspec.c +175 -62
  377. data/vendor/libgit2/src/refspec.h +10 -25
  378. data/vendor/libgit2/src/remote.c +1741 -723
  379. data/vendor/libgit2/src/remote.h +17 -5
  380. data/vendor/libgit2/src/repository.c +1505 -421
  381. data/vendor/libgit2/src/repository.h +95 -15
  382. data/vendor/libgit2/src/reset.c +63 -26
  383. data/vendor/libgit2/src/revert.c +232 -0
  384. data/vendor/libgit2/src/revparse.c +94 -80
  385. data/vendor/libgit2/src/revwalk.c +427 -194
  386. data/vendor/libgit2/src/revwalk.h +14 -5
  387. data/vendor/libgit2/src/settings.c +290 -0
  388. data/vendor/libgit2/src/sha1_lookup.c +16 -159
  389. data/vendor/libgit2/src/sha1_lookup.h +5 -4
  390. data/vendor/libgit2/src/signature.c +138 -26
  391. data/vendor/libgit2/src/signature.h +5 -0
  392. data/vendor/libgit2/src/sortedcache.c +395 -0
  393. data/vendor/libgit2/src/sortedcache.h +180 -0
  394. data/vendor/libgit2/src/stash.c +629 -168
  395. data/vendor/libgit2/src/status.c +125 -75
  396. data/vendor/libgit2/src/status.h +4 -2
  397. data/vendor/libgit2/src/stdalloc.c +120 -0
  398. data/vendor/libgit2/src/stdalloc.h +17 -0
  399. data/vendor/libgit2/src/stream.h +86 -0
  400. data/vendor/libgit2/src/streams/mbedtls.c +483 -0
  401. data/vendor/libgit2/src/streams/mbedtls.h +23 -0
  402. data/vendor/libgit2/src/streams/openssl.c +789 -0
  403. data/vendor/libgit2/src/streams/openssl.h +23 -0
  404. data/vendor/libgit2/src/streams/registry.c +118 -0
  405. data/vendor/libgit2/src/streams/registry.h +19 -0
  406. data/vendor/libgit2/src/streams/socket.c +235 -0
  407. data/vendor/libgit2/src/streams/socket.h +23 -0
  408. data/vendor/libgit2/src/streams/stransport.c +323 -0
  409. data/vendor/libgit2/src/streams/stransport.h +21 -0
  410. data/vendor/libgit2/src/streams/tls.c +73 -0
  411. data/vendor/libgit2/src/streams/tls.h +31 -0
  412. data/vendor/libgit2/src/strmap.c +147 -0
  413. data/vendor/libgit2/src/strmap.h +46 -51
  414. data/vendor/libgit2/src/strnlen.h +24 -0
  415. data/vendor/libgit2/src/submodule.c +1633 -877
  416. data/vendor/libgit2/src/submodule.h +83 -21
  417. data/vendor/libgit2/src/sysdir.c +355 -0
  418. data/vendor/libgit2/src/sysdir.h +119 -0
  419. data/vendor/libgit2/src/tag.c +87 -62
  420. data/vendor/libgit2/src/tag.h +4 -1
  421. data/vendor/libgit2/src/thread-utils.c +3 -0
  422. data/vendor/libgit2/src/thread-utils.h +71 -35
  423. data/vendor/libgit2/src/trace.c +4 -4
  424. data/vendor/libgit2/src/trace.h +11 -3
  425. data/vendor/libgit2/src/trailer.c +416 -0
  426. data/vendor/libgit2/src/transaction.c +382 -0
  427. data/vendor/libgit2/src/transaction.h +14 -0
  428. data/vendor/libgit2/src/transport.c +133 -67
  429. data/vendor/libgit2/src/transports/auth.c +75 -0
  430. data/vendor/libgit2/src/transports/auth.h +64 -0
  431. data/vendor/libgit2/src/transports/auth_negotiate.c +277 -0
  432. data/vendor/libgit2/src/transports/auth_negotiate.h +27 -0
  433. data/vendor/libgit2/src/transports/cred.c +296 -68
  434. data/vendor/libgit2/src/transports/cred.h +16 -0
  435. data/vendor/libgit2/src/transports/cred_helpers.c +4 -0
  436. data/vendor/libgit2/src/transports/git.c +108 -90
  437. data/vendor/libgit2/src/transports/http.c +803 -258
  438. data/vendor/libgit2/src/transports/http.h +25 -0
  439. data/vendor/libgit2/src/transports/local.c +265 -169
  440. data/vendor/libgit2/src/transports/smart.c +255 -45
  441. data/vendor/libgit2/src/transports/smart.h +42 -22
  442. data/vendor/libgit2/src/transports/smart_pkt.c +250 -159
  443. data/vendor/libgit2/src/transports/smart_protocol.c +414 -196
  444. data/vendor/libgit2/src/transports/ssh.c +645 -236
  445. data/vendor/libgit2/src/transports/ssh.h +14 -0
  446. data/vendor/libgit2/src/transports/winhttp.c +809 -353
  447. data/vendor/libgit2/src/tree-cache.c +138 -52
  448. data/vendor/libgit2/src/tree-cache.h +14 -7
  449. data/vendor/libgit2/src/tree.c +620 -259
  450. data/vendor/libgit2/src/tree.h +12 -19
  451. data/vendor/libgit2/src/tsort.c +3 -2
  452. data/vendor/libgit2/src/unix/map.c +25 -7
  453. data/vendor/libgit2/src/unix/posix.h +77 -12
  454. data/vendor/libgit2/src/unix/pthread.h +56 -0
  455. data/vendor/libgit2/src/unix/realpath.c +12 -8
  456. data/vendor/libgit2/src/userdiff.h +208 -0
  457. data/vendor/libgit2/src/util.c +349 -165
  458. data/vendor/libgit2/src/util.h +167 -85
  459. data/vendor/libgit2/src/varint.c +43 -0
  460. data/vendor/libgit2/src/varint.h +17 -0
  461. data/vendor/libgit2/src/vector.c +156 -33
  462. data/vendor/libgit2/src/vector.h +41 -5
  463. data/vendor/libgit2/src/win32/dir.c +22 -42
  464. data/vendor/libgit2/src/win32/dir.h +7 -5
  465. data/vendor/libgit2/src/win32/error.c +6 -32
  466. data/vendor/libgit2/src/win32/error.h +4 -2
  467. data/vendor/libgit2/src/win32/findfile.c +62 -69
  468. data/vendor/libgit2/src/win32/findfile.h +5 -13
  469. data/vendor/libgit2/src/win32/git2.rc +44 -0
  470. data/vendor/libgit2/src/win32/map.c +39 -11
  471. data/vendor/libgit2/src/win32/mingw-compat.h +10 -11
  472. data/vendor/libgit2/src/win32/msvc-compat.h +10 -33
  473. data/vendor/libgit2/src/win32/path_w32.c +476 -0
  474. data/vendor/libgit2/src/win32/path_w32.h +104 -0
  475. data/vendor/libgit2/src/win32/posix.h +35 -30
  476. data/vendor/libgit2/src/win32/posix_w32.c +659 -327
  477. data/vendor/libgit2/src/win32/precompiled.h +7 -2
  478. data/vendor/libgit2/src/win32/reparse.h +57 -0
  479. data/vendor/libgit2/src/win32/thread.c +258 -0
  480. data/vendor/libgit2/src/win32/thread.h +64 -0
  481. data/vendor/libgit2/src/win32/utf-conv.c +127 -62
  482. data/vendor/libgit2/src/win32/utf-conv.h +47 -6
  483. data/vendor/libgit2/src/win32/version.h +21 -4
  484. data/vendor/libgit2/src/win32/w32_buffer.c +54 -0
  485. data/vendor/libgit2/src/win32/w32_buffer.h +20 -0
  486. data/vendor/libgit2/src/win32/w32_crtdbg_stacktrace.c +438 -0
  487. data/vendor/libgit2/src/win32/w32_crtdbg_stacktrace.h +129 -0
  488. data/vendor/libgit2/src/win32/w32_stack.c +193 -0
  489. data/vendor/libgit2/src/win32/w32_stack.h +140 -0
  490. data/vendor/libgit2/src/win32/w32_util.c +95 -0
  491. data/vendor/libgit2/src/win32/w32_util.h +170 -0
  492. data/vendor/libgit2/src/win32/win32-compat.h +52 -0
  493. data/vendor/libgit2/src/worktree.c +578 -0
  494. data/vendor/libgit2/src/worktree.h +39 -0
  495. data/vendor/libgit2/src/xdiff/xdiff.h +33 -18
  496. data/vendor/libgit2/src/xdiff/xdiffi.c +578 -88
  497. data/vendor/libgit2/src/xdiff/xdiffi.h +3 -2
  498. data/vendor/libgit2/src/xdiff/xemit.c +106 -45
  499. data/vendor/libgit2/src/xdiff/xemit.h +3 -3
  500. data/vendor/libgit2/src/xdiff/xhistogram.c +5 -4
  501. data/vendor/libgit2/src/xdiff/xinclude.h +3 -2
  502. data/vendor/libgit2/src/xdiff/xmacros.h +2 -2
  503. data/vendor/libgit2/src/xdiff/xmerge.c +167 -48
  504. data/vendor/libgit2/src/xdiff/xpatience.c +42 -10
  505. data/vendor/libgit2/src/xdiff/xprepare.c +14 -14
  506. data/vendor/libgit2/src/xdiff/xprepare.h +2 -2
  507. data/vendor/libgit2/src/xdiff/xtypes.h +2 -2
  508. data/vendor/libgit2/src/xdiff/xutils.c +60 -56
  509. data/vendor/libgit2/src/xdiff/xutils.h +3 -5
  510. data/vendor/libgit2/src/zstream.c +205 -0
  511. data/vendor/libgit2/src/zstream.h +53 -0
  512. metadata +281 -233
  513. data/Rakefile +0 -61
  514. data/ext/rugged/rugged_diff_patch.c +0 -169
  515. data/lib/rugged/diff/patch.rb +0 -28
  516. data/test/blob_test.rb +0 -341
  517. data/test/branch_test.rb +0 -199
  518. data/test/commit_test.rb +0 -104
  519. data/test/config_test.rb +0 -45
  520. data/test/coverage/cover.rb +0 -133
  521. data/test/diff_test.rb +0 -777
  522. data/test/errors_test.rb +0 -34
  523. data/test/fixtures/alternate/objects/14/6ae76773c91e3b1d00cf7a338ec55ae58297e2 +0 -0
  524. data/test/fixtures/alternate/objects/14/9c32d47e99d0a3572ff1e70a2e0051bbf347a9 +0 -0
  525. data/test/fixtures/alternate/objects/14/fb3108588f9421bf764041e5e3ac305eb6277f +0 -0
  526. data/test/fixtures/archive.tar.gz +0 -0
  527. data/test/fixtures/attr/attr0 +0 -1
  528. data/test/fixtures/attr/attr1 +0 -29
  529. data/test/fixtures/attr/attr2 +0 -21
  530. data/test/fixtures/attr/attr3 +0 -4
  531. data/test/fixtures/attr/binfile +0 -1
  532. data/test/fixtures/attr/dir/file +0 -0
  533. data/test/fixtures/attr/file +0 -1
  534. data/test/fixtures/attr/gitattributes +0 -29
  535. data/test/fixtures/attr/gitignore +0 -2
  536. data/test/fixtures/attr/ign +0 -1
  537. data/test/fixtures/attr/macro_bad +0 -1
  538. data/test/fixtures/attr/macro_test +0 -1
  539. data/test/fixtures/attr/root_test1 +0 -1
  540. data/test/fixtures/attr/root_test2 +0 -6
  541. data/test/fixtures/attr/root_test3 +0 -19
  542. data/test/fixtures/attr/root_test4.txt +0 -14
  543. data/test/fixtures/attr/sub/abc +0 -37
  544. data/test/fixtures/attr/sub/dir/file +0 -0
  545. data/test/fixtures/attr/sub/file +0 -1
  546. data/test/fixtures/attr/sub/ign/file +0 -1
  547. data/test/fixtures/attr/sub/ign/sub/file +0 -1
  548. data/test/fixtures/attr/sub/sub/dir +0 -0
  549. data/test/fixtures/attr/sub/sub/file +0 -1
  550. data/test/fixtures/attr/sub/sub/subsub.txt +0 -1
  551. data/test/fixtures/attr/sub/subdir_test1 +0 -2
  552. data/test/fixtures/attr/sub/subdir_test2.txt +0 -1
  553. data/test/fixtures/diff/another.txt +0 -38
  554. data/test/fixtures/diff/readme.txt +0 -36
  555. data/test/fixtures/mergedrepo/conflicts-one.txt +0 -5
  556. data/test/fixtures/mergedrepo/conflicts-two.txt +0 -5
  557. data/test/fixtures/mergedrepo/one.txt +0 -10
  558. data/test/fixtures/mergedrepo/two.txt +0 -12
  559. data/test/fixtures/status/current_file +0 -1
  560. data/test/fixtures/status/ignored_file +0 -1
  561. data/test/fixtures/status/modified_file +0 -2
  562. data/test/fixtures/status/new_file +0 -1
  563. data/test/fixtures/status/staged_changes +0 -2
  564. data/test/fixtures/status/staged_changes_modified_file +0 -3
  565. data/test/fixtures/status/staged_delete_modified_file +0 -1
  566. data/test/fixtures/status/staged_new_file +0 -1
  567. data/test/fixtures/status/staged_new_file_modified_file +0 -2
  568. data/test/fixtures/status/subdir/current_file +0 -1
  569. data/test/fixtures/status/subdir/modified_file +0 -2
  570. data/test/fixtures/status/subdir/new_file +0 -1
  571. data/test/fixtures/status/subdir.txt +0 -2
  572. data/test/fixtures/status//350/277/231 +0 -1
  573. data/test/fixtures/testrepo.git/HEAD +0 -1
  574. data/test/fixtures/testrepo.git/config +0 -13
  575. data/test/fixtures/testrepo.git/description +0 -1
  576. data/test/fixtures/testrepo.git/index +0 -0
  577. data/test/fixtures/testrepo.git/info/exclude +0 -6
  578. data/test/fixtures/testrepo.git/logs/HEAD +0 -3
  579. data/test/fixtures/testrepo.git/logs/refs/heads/master +0 -3
  580. data/test/fixtures/testrepo.git/logs/refs/notes/commits +0 -1
  581. data/test/fixtures/testrepo.git/objects/0c/37a5391bbff43c37f0d0371823a5509eed5b1d +0 -0
  582. data/test/fixtures/testrepo.git/objects/13/85f264afb75a56a5bec74243be9b367ba4ca08 +0 -0
  583. data/test/fixtures/testrepo.git/objects/18/1037049a54a1eb5fab404658a3a250b44335d7 +0 -0
  584. data/test/fixtures/testrepo.git/objects/18/10dff58d8a660512d4832e740f692884338ccd +0 -0
  585. data/test/fixtures/testrepo.git/objects/2d/2eff63372b08adf0a9eb84109ccf7d19e2f3a2 +0 -0
  586. data/test/fixtures/testrepo.git/objects/36/060c58702ed4c2a40832c51758d5344201d89a +0 -2
  587. data/test/fixtures/testrepo.git/objects/44/1034f860c1d5d90e4188d11ae0d325176869a8 +0 -1
  588. data/test/fixtures/testrepo.git/objects/45/b983be36b73c0788dc9cbcb76cbb80fc7bb057 +0 -0
  589. data/test/fixtures/testrepo.git/objects/4a/202b346bb0fb0db7eff3cffeb3c70babbd2045 +0 -2
  590. data/test/fixtures/testrepo.git/objects/5b/5b025afb0b4c913b4c338a42934a3863bf3644 +0 -2
  591. data/test/fixtures/testrepo.git/objects/60/d415052a33de2150bf68757f6461df4f563ae4 +0 -0
  592. data/test/fixtures/testrepo.git/objects/61/9f9935957e010c419cb9d15621916ddfcc0b96 +0 -0
  593. data/test/fixtures/testrepo.git/objects/68/8a8f4ef7496901d15322972f96e212a9e466cc +0 -1
  594. data/test/fixtures/testrepo.git/objects/75/057dd4114e74cca1d750d0aee1647c903cb60a +0 -0
  595. data/test/fixtures/testrepo.git/objects/77/71329dfa3002caf8c61a0ceb62a31d09023f37 +0 -0
  596. data/test/fixtures/testrepo.git/objects/81/4889a078c031f61ed08ab5fa863aea9314344d +0 -0
  597. data/test/fixtures/testrepo.git/objects/84/96071c1b46c854b31185ea97743be6a8774479 +0 -0
  598. data/test/fixtures/testrepo.git/objects/94/eca2de348d5f672faf56b0decafa5937e3235e +0 -0
  599. data/test/fixtures/testrepo.git/objects/9b/7384fe1676186192842f5d3e129457b62db9e3 +0 -0
  600. data/test/fixtures/testrepo.git/objects/9f/d738e8f7967c078dceed8190330fc8648ee56a +0 -3
  601. data/test/fixtures/testrepo.git/objects/a4/a7dce85cf63874e984719f4fdd239f5145052f +0 -2
  602. data/test/fixtures/testrepo.git/objects/a7/1586c1dfe8a71c6cbf6c129f404c5642ff31bd +0 -0
  603. data/test/fixtures/testrepo.git/objects/a8/233120f6ad708f843d861ce2b7228ec4e3dec6 +0 -0
  604. data/test/fixtures/testrepo.git/objects/b7/4713326bc972cc15751ed504dca6f6f3b91f7a +0 -3
  605. data/test/fixtures/testrepo.git/objects/be/3563ae3f795b2b4353bcce3a527ad0a4f7f644 +0 -3
  606. data/test/fixtures/testrepo.git/objects/c4/7800c7266a2be04c571c04d5a6614691ea99bd +0 -3
  607. data/test/fixtures/testrepo.git/objects/c4/dc1555e4d4fa0e0c9c3fc46734c7c35b3ce90b +0 -0
  608. data/test/fixtures/testrepo.git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 +0 -0
  609. data/test/fixtures/testrepo.git/objects/f6/0079018b664e4e79329a7ef9559c8d9e0378d1 +0 -0
  610. data/test/fixtures/testrepo.git/objects/fa/49b077972391ad58037050f2a75f74e3671e92 +0 -0
  611. data/test/fixtures/testrepo.git/objects/fd/093bff70906175335656e6ce6ae05783708765 +0 -0
  612. data/test/fixtures/testrepo.git/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.idx +0 -0
  613. data/test/fixtures/testrepo.git/objects/pack/pack-d7c6adf9f61318f041845b01440d09aa7a91e1b5.pack +0 -0
  614. data/test/fixtures/testrepo.git/packed-refs +0 -2
  615. data/test/fixtures/testrepo.git/refs/heads/master +0 -1
  616. data/test/fixtures/testrepo.git/refs/notes/commits +0 -1
  617. data/test/fixtures/testrepo.git/refs/tags/v0.9 +0 -1
  618. data/test/fixtures/testrepo.git/refs/tags/v1.0 +0 -1
  619. data/test/fixtures/text_file.md +0 -464
  620. data/test/fixtures/unsymlinked.git/HEAD +0 -1
  621. data/test/fixtures/unsymlinked.git/config +0 -6
  622. data/test/fixtures/unsymlinked.git/description +0 -1
  623. data/test/fixtures/unsymlinked.git/info/exclude +0 -2
  624. data/test/fixtures/unsymlinked.git/objects/08/8b64704e0d6b8bd061dea879418cb5442a3fbf +0 -0
  625. data/test/fixtures/unsymlinked.git/objects/13/a5e939bca25940c069fd2169d993dba328e30b +0 -0
  626. data/test/fixtures/unsymlinked.git/objects/19/bf568e59e3a0b363cafb4106226e62d4a4c41c +0 -0
  627. data/test/fixtures/unsymlinked.git/objects/58/1fadd35b4cf320d102a152f918729011604773 +0 -0
  628. data/test/fixtures/unsymlinked.git/objects/5c/87b6791e8b13da658a14d1ef7e09b5dc3bac8c +0 -0
  629. data/test/fixtures/unsymlinked.git/objects/6f/e5f5398af85fb3de8a6aba0339b6d3bfa26a27 +0 -0
  630. data/test/fixtures/unsymlinked.git/objects/7f/ccd75616ec188b8f1b23d67506a334cc34a49d +0 -0
  631. data/test/fixtures/unsymlinked.git/objects/80/6999882bf91d24241e4077906b9017605eb1f3 +0 -0
  632. data/test/fixtures/unsymlinked.git/objects/83/7d176303c5005505ec1e4a30231c40930c0230 +0 -0
  633. data/test/fixtures/unsymlinked.git/objects/a8/595ccca04f40818ae0155c8f9c77a230e597b6 +0 -2
  634. data/test/fixtures/unsymlinked.git/objects/cf/8f1cf5cce859c438d6cc067284cb5e161206e7 +0 -0
  635. data/test/fixtures/unsymlinked.git/objects/d5/278d05c8607ec420bfee4cf219fbc0eeebfd6a +0 -0
  636. data/test/fixtures/unsymlinked.git/objects/f4/e16fb76536591a41454194058d048d8e4dd2e9 +0 -0
  637. data/test/fixtures/unsymlinked.git/objects/f9/e65619d93fdf2673882e0a261c5e93b1a84006 +0 -0
  638. data/test/fixtures/unsymlinked.git/refs/heads/exe-file +0 -1
  639. data/test/fixtures/unsymlinked.git/refs/heads/master +0 -1
  640. data/test/fixtures/unsymlinked.git/refs/heads/reg-file +0 -1
  641. data/test/index_test.rb +0 -333
  642. data/test/lib_test.rb +0 -127
  643. data/test/note_test.rb +0 -158
  644. data/test/object_test.rb +0 -43
  645. data/test/reference_test.rb +0 -207
  646. data/test/remote_test.rb +0 -324
  647. data/test/repo_pack_test.rb +0 -24
  648. data/test/repo_reset_test.rb +0 -82
  649. data/test/repo_test.rb +0 -402
  650. data/test/tag_test.rb +0 -68
  651. data/test/test_helper.rb +0 -92
  652. data/test/tree_test.rb +0 -91
  653. data/test/walker_test.rb +0 -88
  654. data/vendor/libgit2/Makefile.embed +0 -42
  655. data/vendor/libgit2/include/git2/push.h +0 -131
  656. data/vendor/libgit2/include/git2/threads.h +0 -50
  657. data/vendor/libgit2/src/amiga/map.c +0 -48
  658. data/vendor/libgit2/src/bswap.h +0 -97
  659. data/vendor/libgit2/src/compress.c +0 -53
  660. data/vendor/libgit2/src/config_file.h +0 -60
  661. data/vendor/libgit2/src/delta-apply.c +0 -134
  662. data/vendor/libgit2/src/delta-apply.h +0 -50
  663. data/vendor/libgit2/src/diff_patch.c +0 -995
  664. data/vendor/libgit2/src/diff_patch.h +0 -46
  665. data/vendor/libgit2/src/hashsig.h +0 -72
  666. data/vendor/libgit2/src/merge_file.h +0 -71
  667. data/vendor/libgit2/src/win32/pthread.c +0 -144
  668. data/vendor/libgit2/src/win32/pthread.h +0 -50
@@ -1,29 +1,15 @@
1
1
  /*
2
- * The MIT License
3
- *
4
- * Copyright (c) 2013 GitHub, Inc
5
- *
6
- * Permission is hereby granted, free of charge, to any person obtaining a copy
7
- * of this software and associated documentation files (the "Software"), to deal
8
- * in the Software without restriction, including without limitation the rights
9
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
- * copies of the Software, and to permit persons to whom the Software is
11
- * furnished to do so, subject to the following conditions:
12
- *
13
- * The above copyright notice and this permission notice shall be included in
14
- * all copies or substantial portions of the Software.
15
- *
16
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
- * THE SOFTWARE.
2
+ * Copyright (C) the Rugged contributors. All rights reserved.
3
+ *
4
+ * This file is part of Rugged, distributed under the MIT license.
5
+ * For full terms see the included LICENSE file.
23
6
  */
24
7
 
25
8
  #include "rugged.h"
26
9
  #include <git2/sys/repository.h>
10
+ #include <git2/sys/odb_backend.h>
11
+ #include <git2/sys/refdb_backend.h>
12
+ #include <git2/refs.h>
27
13
 
28
14
  extern VALUE rb_mRugged;
29
15
  extern VALUE rb_eRuggedError;
@@ -31,7 +17,15 @@ extern VALUE rb_cRuggedIndex;
31
17
  extern VALUE rb_cRuggedConfig;
32
18
  extern VALUE rb_cRuggedBackend;
33
19
  extern VALUE rb_cRuggedRemote;
20
+ extern VALUE rb_cRuggedCommit;
21
+ extern VALUE rb_cRuggedTag;
22
+ extern VALUE rb_cRuggedTree;
34
23
  extern VALUE rb_cRuggedReference;
24
+ extern VALUE rb_cRuggedBackend;
25
+
26
+ extern VALUE rb_cRuggedCredPlaintext;
27
+ extern VALUE rb_cRuggedCredSshKey;
28
+ extern VALUE rb_cRuggedCredDefault;
35
29
 
36
30
  VALUE rb_cRuggedRepo;
37
31
  VALUE rb_cRuggedOdbObject;
@@ -131,7 +125,7 @@ void rb_git_repo__free(git_repository *repo)
131
125
  git_repository_free(repo);
132
126
  }
133
127
 
134
- static VALUE rugged_repo_new(VALUE klass, git_repository *repo)
128
+ VALUE rugged_repo_new(VALUE klass, git_repository *repo)
135
129
  {
136
130
  VALUE rb_repo = Data_Wrap_Struct(klass, NULL, &rb_git_repo__free, repo);
137
131
 
@@ -175,9 +169,83 @@ static void load_alternates(git_repository *repo, VALUE rb_alternates)
175
169
  rugged_exception_check(error);
176
170
  }
177
171
 
172
+ static void rugged_repo_new_with_backend(git_repository **repo, VALUE rb_path, VALUE rb_backend)
173
+ {
174
+ char *path;
175
+
176
+ git_odb *odb = NULL;
177
+ git_odb_backend *odb_backend = NULL;
178
+ git_refdb *refdb = NULL;
179
+ git_refdb_backend *refdb_backend = NULL;
180
+ git_reference *head = NULL;
181
+ rugged_backend *backend;
182
+
183
+ int error = 0;
184
+
185
+ FilePathValue(rb_path);
186
+ path = StringValueCStr(rb_path);
187
+
188
+ if (rb_obj_is_kind_of(rb_backend, rb_cRuggedBackend) == Qfalse) {
189
+ rb_raise(rb_eRuggedError, "Backend must be an instance of Rugged::Backend");
190
+ }
191
+
192
+ Data_Get_Struct(rb_backend, rugged_backend, backend);
193
+
194
+ error = git_odb_new(&odb);
195
+ if (error) goto cleanup;
196
+
197
+ error = backend->odb_backend(&odb_backend, backend, path);
198
+ if (error) goto cleanup;
199
+
200
+ error = git_odb_add_backend(odb, odb_backend, 1);
201
+ if (error) {
202
+ assert(odb_backend->free);
203
+ odb_backend->free(odb_backend);
204
+ goto cleanup;
205
+ }
206
+
207
+ error = git_repository_wrap_odb(repo, odb);
208
+ if (error) goto cleanup;
209
+
210
+ error = git_refdb_new(&refdb, *repo);
211
+ if (error) goto cleanup;
212
+
213
+ error = backend->refdb_backend(&refdb_backend, backend, path);
214
+ if (error) {
215
+ assert(refdb_backend->free);
216
+ refdb_backend->free(refdb_backend);
217
+ goto cleanup;
218
+ }
219
+
220
+ error = git_refdb_set_backend(refdb, refdb_backend);
221
+ if (error) goto cleanup;
222
+
223
+ git_repository_set_refdb(*repo, refdb);
224
+
225
+ error = git_reference_lookup(&head, *repo, "HEAD");
226
+
227
+ if (error == GIT_ENOTFOUND) {
228
+ giterr_clear();
229
+ error = git_reference_symbolic_create(&head, *repo, "HEAD", "refs/heads/master", 0, NULL);
230
+ }
231
+
232
+ if (!error) {
233
+ git_reference_free(head);
234
+ return;
235
+ }
236
+
237
+ cleanup:
238
+ git_repository_free(*repo);
239
+ git_odb_free(odb);
240
+ git_refdb_free(refdb);
241
+
242
+ rugged_exception_check(error);
243
+ }
244
+
178
245
  /*
179
246
  * call-seq:
180
- * Repository.bare(path[, alternates]) -> repository
247
+ * Repository.bare(path[, alternates]) -> repository OR
248
+ * Repository.bare(path[, options]) -> repository
181
249
  *
182
250
  * Open a bare Git repository at +path+ and return a +Repository+
183
251
  * object representing it.
@@ -186,23 +254,52 @@ static void load_alternates(git_repository *repo, VALUE rb_alternates)
186
254
  * any +.git+ directory discovery, won't try to load the config options to
187
255
  * determine whether the repository is bare and won't try to load the workdir.
188
256
  *
189
- * Optionally, you can pass a list of alternate object folders.
257
+ * Optionally, you can pass a list of alternate object folders or an options Hash.
190
258
  *
191
259
  * Rugged::Repository.bare(path, ['./other/repo/.git/objects'])
260
+ * Rugged::Repository.bare(path, opts)
261
+ *
262
+ * The following options can be passed in the +options+ Hash:
263
+ *
264
+ * :backend ::
265
+ * A Rugged::Backend instance
266
+ * :alternates ::
267
+ * A list of alternate object folders.
268
+ * Rugged::Repository.bare(path, :alternates => ['./other/repo/.git/objects'])
192
269
  */
193
270
  static VALUE rb_git_repo_open_bare(int argc, VALUE *argv, VALUE klass)
194
271
  {
195
- git_repository *repo;
272
+ git_repository *repo = NULL;
196
273
  int error = 0;
197
- VALUE rb_path, rb_alternates;
274
+ VALUE rb_path, rb_options, rb_alternates = 0;
198
275
 
199
- rb_scan_args(argc, argv, "11", &rb_path, &rb_alternates);
200
- Check_Type(rb_path, T_STRING);
276
+ rb_scan_args(argc, argv, "11", &rb_path, &rb_options);
201
277
 
202
- error = git_repository_open_bare(&repo, StringValueCStr(rb_path));
203
- rugged_exception_check(error);
278
+ if (!NIL_P(rb_options) && TYPE(rb_options) == T_ARRAY)
279
+ rb_alternates = rb_options;
280
+
281
+ if (!NIL_P(rb_options) && TYPE(rb_options) == T_HASH) {
282
+ /* Check for `:backend` */
283
+ VALUE rb_backend = rb_hash_aref(rb_options, CSTR2SYM("backend"));
284
+
285
+ if (!NIL_P(rb_backend)) {
286
+ rugged_repo_new_with_backend(&repo, rb_path, rb_backend);
287
+ }
288
+
289
+ /* Check for `:alternates` */
290
+ rb_alternates = rb_hash_aref(rb_options, CSTR2SYM("alternates"));
291
+ }
292
+
293
+ if (!repo) {
294
+ FilePathValue(rb_path);
295
+
296
+ error = git_repository_open_bare(&repo, StringValueCStr(rb_path));
297
+ rugged_exception_check(error);
298
+ }
204
299
 
205
- load_alternates(repo, rb_alternates);
300
+ if (rb_alternates) {
301
+ load_alternates(repo, rb_alternates);
302
+ }
206
303
 
207
304
  return rugged_repo_new(klass, repo);
208
305
  }
@@ -214,7 +311,7 @@ static VALUE rb_git_repo_open_bare(int argc, VALUE *argv, VALUE klass)
214
311
  * Open a Git repository in the given +path+ and return a +Repository+ object
215
312
  * representing it. An exception will be thrown if +path+ doesn't point to a
216
313
  * valid repository. If you need to create a repository from scratch, use
217
- * Rugged::Repository.init instead.
314
+ * Rugged::Repository.init_at instead.
218
315
  *
219
316
  * The +path+ must point to either the actual folder (+.git+) of a Git repository,
220
317
  * or to the directorly that contains the +.git+ folder.
@@ -228,7 +325,7 @@ static VALUE rb_git_repo_open_bare(int argc, VALUE *argv, VALUE klass)
228
325
  *
229
326
  * Examples:
230
327
  *
231
- * Rugged::Repository.new('~/test/.git') #=> #<Rugged::Repository:0x108849488>
328
+ * Rugged::Repository.new('test/.git') #=> #<Rugged::Repository:0x108849488>
232
329
  * Rugged::Repository.new(path, :alternates => ['./other/repo/.git/objects'])
233
330
  */
234
331
  static VALUE rb_git_repo_new(int argc, VALUE *argv, VALUE klass)
@@ -238,7 +335,7 @@ static VALUE rb_git_repo_new(int argc, VALUE *argv, VALUE klass)
238
335
  VALUE rb_path, rb_options;
239
336
 
240
337
  rb_scan_args(argc, argv, "10:", &rb_path, &rb_options);
241
- Check_Type(rb_path, T_STRING);
338
+ FilePathValue(rb_path);
242
339
 
243
340
  error = git_repository_open(&repo, StringValueCStr(rb_path));
244
341
  rugged_exception_check(error);
@@ -253,7 +350,7 @@ static VALUE rb_git_repo_new(int argc, VALUE *argv, VALUE klass)
253
350
 
254
351
  /*
255
352
  * call-seq:
256
- * Repository.init_at(path, is_bare = false) -> repository
353
+ * Repository.init_at(path, is_bare = false, opts = {}) -> repository
257
354
  *
258
355
  * Initialize a Git repository in +path+. This implies creating all the
259
356
  * necessary files on the FS, or re-initializing an already existing
@@ -265,77 +362,58 @@ static VALUE rb_git_repo_new(int argc, VALUE *argv, VALUE klass)
265
362
  * of +path+. Non-bare repositories are created in a +.git+ folder and
266
363
  * use +path+ as working directory.
267
364
  *
268
- * Rugged::Repository.init_at('~/repository', :bare) #=> #<Rugged::Repository:0x108849488>
365
+ * The following options can be passed in the +options+ Hash:
366
+ *
367
+ * :backend ::
368
+ * A Rugged::Backend instance
369
+ *
370
+ *
371
+ * Rugged::Repository.init_at('repository', :bare) #=> #<Rugged::Repository:0x108849488>
269
372
  */
270
373
  static VALUE rb_git_repo_init_at(int argc, VALUE *argv, VALUE klass)
271
374
  {
272
- git_repository *repo;
273
- VALUE rb_path, rb_is_bare;
274
- int error, is_bare = 0;
275
-
276
- rb_scan_args(argc, argv, "11", &rb_path, &rb_is_bare);
277
- Check_Type(rb_path, T_STRING);
278
-
279
- if (!NIL_P(rb_is_bare))
280
- is_bare = rb_is_bare ? 1 : 0;
375
+ git_repository *repo = NULL;
376
+ VALUE rb_path, rb_is_bare, rb_options;
377
+ int error;
281
378
 
282
- error = git_repository_init(&repo, StringValueCStr(rb_path), is_bare);
283
- rugged_exception_check(error);
379
+ rb_scan_args(argc, argv, "11:", &rb_path, &rb_is_bare, &rb_options);
380
+ FilePathValue(rb_path);
284
381
 
285
- return rugged_repo_new(klass, repo);
286
- }
382
+ if (!NIL_P(rb_options)) {
383
+ /* Check for `:backend` */
384
+ VALUE rb_backend = rb_hash_aref(rb_options, CSTR2SYM("backend"));
287
385
 
288
- struct clone_fetch_callback_payload
289
- {
290
- VALUE proc;
291
- VALUE exception;
292
- const git_transfer_progress *stats;
293
- };
386
+ if (rb_backend && !NIL_P(rb_backend)) {
387
+ rugged_repo_new_with_backend(&repo, rb_path, rb_backend);
388
+ }
389
+ }
294
390
 
295
- static VALUE clone_fetch_callback_inner(struct clone_fetch_callback_payload *fetch_payload)
296
- {
297
- rb_funcall(fetch_payload->proc, id_call, 4,
298
- UINT2NUM(fetch_payload->stats->total_objects),
299
- UINT2NUM(fetch_payload->stats->indexed_objects),
300
- UINT2NUM(fetch_payload->stats->received_objects),
301
- INT2FIX(fetch_payload->stats->received_bytes));
302
- return GIT_OK;
303
- }
391
+ if(!repo) {
392
+ error = git_repository_init(&repo, StringValueCStr(rb_path), RTEST(rb_is_bare));
393
+ rugged_exception_check(error);
394
+ }
304
395
 
305
- static VALUE clone_fetch_callback_rescue(struct clone_fetch_callback_payload *fetch_payload, VALUE exception)
306
- {
307
- fetch_payload->exception = exception;
308
- return GIT_ERROR;
396
+ return rugged_repo_new(klass, repo);
309
397
  }
310
398
 
311
- static int clone_fetch_callback(const git_transfer_progress *stats, void *payload)
399
+ static void parse_clone_options(git_clone_options *ret, VALUE rb_options, struct rugged_remote_cb_payload *remote_payload)
312
400
  {
313
- struct clone_fetch_callback_payload *fetch_payload = payload;
314
- fetch_payload->stats = stats;
315
- return rb_rescue(clone_fetch_callback_inner, (VALUE) fetch_payload,
316
- clone_fetch_callback_rescue, (VALUE) fetch_payload);
317
- }
401
+ VALUE val;
318
402
 
319
- static void parse_clone_options(git_clone_options *ret, VALUE rb_options_hash, struct clone_fetch_callback_payload *fetch_progress_payload)
320
- {
321
- if (!NIL_P(rb_options_hash)) {
322
- VALUE val;
403
+ if (NIL_P(rb_options))
404
+ return;
323
405
 
324
- val = rb_hash_aref(rb_options_hash, CSTR2SYM("bare"));
325
- if (RTEST(val))
326
- ret->bare = 1;
406
+ val = rb_hash_aref(rb_options, CSTR2SYM("bare"));
407
+ if (RTEST(val))
408
+ ret->bare = 1;
327
409
 
328
- val = rb_hash_aref(rb_options_hash, CSTR2SYM("progress"));
329
- if (RTEST(val)) {
330
- if (rb_respond_to(val, rb_intern("call"))) {
331
- fetch_progress_payload->proc = val;
332
- ret->fetch_progress_payload = fetch_progress_payload;
333
- ret->fetch_progress_cb = clone_fetch_callback;
334
- } else {
335
- rb_raise(rb_eArgError, "Expected a Proc or an object that responds to call (:progress).");
336
- }
337
- }
410
+ val = rb_hash_aref(rb_options, CSTR2SYM("checkout_branch"));
411
+ if (!NIL_P(val)) {
412
+ Check_Type(val, T_STRING);
413
+ ret->checkout_branch = StringValueCStr(val);
338
414
  }
415
+
416
+ rugged_remote_init_callbacks_and_payload_from_options(rb_options, &ret->fetch_opts.callbacks, remote_payload);
339
417
  }
340
418
 
341
419
  /*
@@ -350,36 +428,60 @@ static void parse_clone_options(git_clone_options *ret, VALUE rb_options_hash, s
350
428
  * If +true+, the clone will be created as a bare repository.
351
429
  * Defaults to +false+.
352
430
  *
431
+ * :checkout_branch ::
432
+ * The name of a branch to checkout. Defaults to the remote's +HEAD+.
433
+ *
434
+ * :remote ::
435
+ * The name to give to the "origin" remote. Defaults to <tt>"origin"</tt>.
436
+ *
437
+ * :ignore_cert_errors ::
438
+ * If set to +true+, errors while validating the remote's host certificate will be ignored.
439
+ *
440
+ * :credentials ::
441
+ * The credentials to use for the clone operation. Can be either an instance of one
442
+ * of the Rugged::Credentials types, or a proc returning one of the former.
443
+ * The proc will be called with the +url+, the +username+ from the url (if applicable) and
444
+ * a list of applicable credential types.
445
+ *
353
446
  * :progress ::
447
+ * A callback that will be executed with the textual progress received from the remote.
448
+ * This is the text send over the progress side-band (ie. the "counting objects" output).
449
+ *
450
+ * :transfer_progress ::
354
451
  * A callback that will be executed to report clone progress information. It will be passed
355
- * the amount of +total_objects+, +indexed_objects+, +received_objects+ and +received_bytes+.
452
+ * the amount of +total_objects+, +indexed_objects+, +received_objects+, +local_objects+,
453
+ * +total_deltas+, +indexed_deltas+, and +received_bytes+.
454
+ *
455
+ * :update_tips ::
456
+ * A callback that will be executed each time a reference was updated locally. It will be
457
+ * passed the +refname+, +old_oid+ and +new_oid+.
356
458
  *
357
459
  * Example:
358
460
  *
359
- * progress = lambda { |total_objects, indexed_objects, received_objects, received_bytes|
360
- * # ...
361
- * }
362
- * Repository.clone_at("https://github.com/libgit2/rugged.git", "./some/dir", :progress => progress)
461
+ * Repository.clone_at("https://github.com/libgit2/rugged.git", "./some/dir", {
462
+ * transfer_progress: lambda { |total_objects, indexed_objects, received_objects, local_objects, total_deltas, indexed_deltas, received_bytes|
463
+ * # ...
464
+ * }
465
+ * })
363
466
  */
364
467
  static VALUE rb_git_repo_clone_at(int argc, VALUE *argv, VALUE klass)
365
468
  {
366
469
  VALUE url, local_path, rb_options_hash;
367
470
  git_clone_options options = GIT_CLONE_OPTIONS_INIT;
368
- struct clone_fetch_callback_payload fetch_payload;
471
+ struct rugged_remote_cb_payload remote_payload = { Qnil, Qnil, Qnil, Qnil, Qnil, Qnil, Qnil, 0 };
369
472
  git_repository *repo;
370
473
  int error;
371
474
 
372
475
  rb_scan_args(argc, argv, "21", &url, &local_path, &rb_options_hash);
373
476
  Check_Type(url, T_STRING);
374
- Check_Type(local_path, T_STRING);
477
+ FilePathValue(local_path);
375
478
 
376
- fetch_payload.proc = Qnil;
377
- fetch_payload.exception = Qnil;
378
- parse_clone_options(&options, rb_options_hash, &fetch_payload);
479
+ parse_clone_options(&options, rb_options_hash, &remote_payload);
379
480
 
380
481
  error = git_clone(&repo, StringValueCStr(url), StringValueCStr(local_path), &options);
381
- if (RTEST(fetch_payload.exception))
382
- rb_exc_raise(fetch_payload.exception);
482
+
483
+ if (RTEST(remote_payload.exception))
484
+ rb_jump_tag(remote_payload.exception);
383
485
  rugged_exception_check(error);
384
486
 
385
487
  return rugged_repo_new(klass, repo);
@@ -476,6 +578,75 @@ static VALUE rb_git_repo_get_config(VALUE self)
476
578
  RB_GIT_REPO_OWNED_GET(rb_cRuggedConfig, config);
477
579
  }
478
580
 
581
+ /*
582
+ * call-seq:
583
+ * repo.ident = ident
584
+ *
585
+ * Set the identity to be used for writing reflogs.
586
+ *
587
+ * +ident+ can be either +nil+ or a Hash containing +name+ and/or +email+ entries.
588
+ */
589
+ static VALUE rb_git_repo_set_ident(VALUE self, VALUE rb_ident) {
590
+ VALUE rb_val;
591
+
592
+ git_repository *repo;
593
+ const char *name = NULL, *email = NULL;
594
+
595
+ Data_Get_Struct(self, git_repository, repo);
596
+
597
+ if (!NIL_P(rb_ident)) {
598
+ Check_Type(rb_ident, T_HASH);
599
+
600
+ if (!NIL_P(rb_val = rb_hash_aref(rb_ident, CSTR2SYM("name")))) {
601
+ Check_Type(rb_val, T_STRING);
602
+ name = StringValueCStr(rb_val);
603
+ }
604
+
605
+ if (!NIL_P(rb_val = rb_hash_aref(rb_ident, CSTR2SYM("email")))) {
606
+ Check_Type(rb_val, T_STRING);
607
+ email = StringValueCStr(rb_val);
608
+ }
609
+ }
610
+
611
+ rugged_exception_check(
612
+ git_repository_set_ident(repo, name, email)
613
+ );
614
+
615
+ return Qnil;
616
+ }
617
+
618
+ /*
619
+ * call-seq:
620
+ * repo.ident -> ident
621
+ *
622
+ * Return a Hash containing the identity that is used to write reflogs.
623
+ *
624
+ * +ident+ is a Hash containing +name+ and/or +email+ entries, or `nil`.
625
+ */
626
+ static VALUE rb_git_repo_get_ident(VALUE self)
627
+ {
628
+ VALUE rb_ident = rb_hash_new();
629
+
630
+ git_repository *repo;
631
+ const char *name = NULL, *email = NULL;
632
+
633
+ Data_Get_Struct(self, git_repository, repo);
634
+
635
+ rugged_exception_check(
636
+ git_repository_ident(&name, &email, repo)
637
+ );
638
+
639
+ if (name) {
640
+ rb_hash_aset(rb_ident, CSTR2SYM("name"), rb_str_new_utf8(name));
641
+ }
642
+
643
+ if (email) {
644
+ rb_hash_aset(rb_ident, CSTR2SYM("email"), rb_str_new_utf8(email));
645
+ }
646
+
647
+ return rb_ident;
648
+ }
649
+
479
650
  /*
480
651
  * call-seq:
481
652
  * repo.merge_base(oid1, oid2, ...)
@@ -506,7 +677,7 @@ static VALUE rb_git_repo_merge_base(VALUE self, VALUE rb_args)
506
677
  rugged_exception_check(error);
507
678
  }
508
679
 
509
- error = git_merge_base_many(&base, repo, input_array, len);
680
+ error = git_merge_base_many(&base, repo, len, input_array);
510
681
  xfree(input_array);
511
682
 
512
683
  if (error == GIT_ENOTFOUND)
@@ -519,134 +690,481 @@ static VALUE rb_git_repo_merge_base(VALUE self, VALUE rb_args)
519
690
 
520
691
  /*
521
692
  * call-seq:
522
- * repo.include?(oid) -> true or false
523
- * repo.exists?(oid) -> true or false
524
- *
525
- * Return whether an object with the given SHA1 OID (represented as
526
- * a 40-character string) exists in the repository.
693
+ * repo.merge_bases(oid1, oid2, ...) -> Array
694
+ * repo.merge_bases(ref1, ref2, ...) -> Array
695
+ * repo.merge_bases(commit1, commit2, ...) -> Array
527
696
  *
528
- * repo.include?("d8786bfc97485e8d7b19b21fb88c8ef1f199fc3f") #=> true
697
+ * Find all merge bases, given two or more commits or oids.
698
+ * Returns an empty array if no merge bases are found.
529
699
  */
530
- static VALUE rb_git_repo_exists(VALUE self, VALUE hex)
700
+ static VALUE rb_git_repo_merge_bases(VALUE self, VALUE rb_args)
531
701
  {
702
+ int error = GIT_OK;
703
+ size_t i, len = (size_t)RARRAY_LEN(rb_args);
532
704
  git_repository *repo;
533
- git_odb *odb;
534
- git_oid oid;
535
- int error;
536
- VALUE rb_result;
705
+ git_oidarray bases = {NULL, 0};
706
+ git_oid *input_array;
707
+
708
+ VALUE rb_bases;
709
+
710
+ if (len < 2)
711
+ rb_raise(rb_eArgError, "wrong number of arguments (%ld for 2+)", RARRAY_LEN(rb_args));
537
712
 
538
713
  Data_Get_Struct(self, git_repository, repo);
539
- Check_Type(hex, T_STRING);
540
714
 
541
- error = git_oid_fromstr(&oid, StringValueCStr(hex));
542
- rugged_exception_check(error);
715
+ input_array = xmalloc(sizeof(git_oid) * len);
543
716
 
544
- error = git_repository_odb(&odb, repo);
545
- rugged_exception_check(error);
717
+ for (i = 0; !error && i < len; ++i) {
718
+ error = rugged_oid_get(&input_array[i], repo, rb_ary_entry(rb_args, i));
719
+ }
546
720
 
547
- rb_result = git_odb_exists(odb, &oid) ? Qtrue : Qfalse;
548
- git_odb_free(odb);
721
+ if (error) {
722
+ xfree(input_array);
723
+ rugged_exception_check(error);
724
+ }
549
725
 
550
- return rb_result;
726
+ error = git_merge_bases_many(&bases, repo, len, input_array);
727
+ xfree(input_array);
728
+
729
+ if (error != GIT_ENOTFOUND)
730
+ rugged_exception_check(error);
731
+
732
+ rb_bases = rb_ary_new2(bases.count);
733
+
734
+ for (i = 0; i < bases.count; ++i) {
735
+ rb_ary_push(rb_bases, rugged_create_oid(&bases.ids[i]));
736
+ }
737
+
738
+ git_oidarray_free(&bases);
739
+
740
+ return rb_bases;
551
741
  }
552
742
 
553
743
  /*
554
744
  * call-seq:
555
- * repo.read(oid) -> str
745
+ * repo.merge_analysis(their_commit) -> Array
556
746
  *
557
- * Read and return the raw data of the object identified by the given +oid+.
747
+ * Analyzes the given commit and determines the opportunities for merging
748
+ * it into the repository's HEAD. Returns an Array containing a combination
749
+ * of the following symbols:
750
+ *
751
+ * :normal ::
752
+ * A "normal" merge is possible, both HEAD and the given commit have
753
+ * diverged from their common ancestor. The divergent commits must be
754
+ * merged.
755
+ *
756
+ * :up_to_date ::
757
+ * The given commit is reachable from HEAD, meaning HEAD is up-to-date
758
+ * and no merge needs to be performed.
759
+ *
760
+ * :fastforward ::
761
+ * The given commit is a fast-forward from HEAD and no merge needs to be
762
+ * performed. HEAD can simply be set to the given commit.
763
+ *
764
+ * :unborn ::
765
+ * The HEAD of the current repository is "unborn" and does not point to
766
+ * a valid commit. No merge can be performed, but the caller may wish
767
+ * to simply set HEAD to the given commit.
558
768
  */
559
- static VALUE rb_git_repo_read(VALUE self, VALUE hex)
769
+ static VALUE rb_git_repo_merge_analysis(int argc, VALUE *argv, VALUE self)
560
770
  {
561
- git_repository *repo;
562
- git_oid oid;
563
771
  int error;
772
+ git_repository *repo;
773
+ git_commit *their_commit;
774
+ git_annotated_commit *annotated_commit;
775
+ git_merge_analysis_t analysis;
776
+ git_merge_preference_t preference;
777
+ VALUE rb_their_commit, result;
778
+
779
+ rb_scan_args(argc, argv, "10", &rb_their_commit);
564
780
 
565
781
  Data_Get_Struct(self, git_repository, repo);
566
- Check_Type(hex, T_STRING);
567
782
 
568
- error = git_oid_fromstr(&oid, StringValueCStr(hex));
783
+ if (TYPE(rb_their_commit) == T_STRING) {
784
+ rb_their_commit = rugged_object_rev_parse(self, rb_their_commit, 1);
785
+ }
786
+
787
+ if (!rb_obj_is_kind_of(rb_their_commit, rb_cRuggedCommit)) {
788
+ rb_raise(rb_eArgError, "Expected a Rugged::Commit.");
789
+ }
790
+
791
+ Data_Get_Struct(rb_their_commit, git_commit, their_commit);
792
+
793
+ error = git_annotated_commit_lookup(&annotated_commit, repo, git_commit_id(their_commit));
569
794
  rugged_exception_check(error);
570
795
 
571
- return rugged_raw_read(repo, &oid);
796
+ error = git_merge_analysis(&analysis, &preference, repo,
797
+ /* hack as we currently only do one commit */
798
+ (const git_annotated_commit **) &annotated_commit, 1);
799
+ git_annotated_commit_free(annotated_commit);
800
+ rugged_exception_check(error);
801
+
802
+ result = rb_ary_new();
803
+ if (analysis & GIT_MERGE_ANALYSIS_NORMAL)
804
+ rb_ary_push(result, CSTR2SYM("normal"));
805
+ if (analysis & GIT_MERGE_ANALYSIS_UP_TO_DATE)
806
+ rb_ary_push(result, CSTR2SYM("up_to_date"));
807
+ if (analysis & GIT_MERGE_ANALYSIS_FASTFORWARD)
808
+ rb_ary_push(result, CSTR2SYM("fastforward"));
809
+ if (analysis & GIT_MERGE_ANALYSIS_UNBORN)
810
+ rb_ary_push(result, CSTR2SYM("unborn"));
811
+
812
+ return result;
572
813
  }
573
814
 
574
815
  /*
575
816
  * call-seq:
576
- * repo.read_header(oid) -> hash
577
- *
578
- * Read and return the header information in +repo+'s ODB
579
- * for the object identified by the given +oid+.
580
- *
581
- * Returns a Hash object with the following key/value pairs:
817
+ * repo.revert_commit(revert_commit, our_commit, options = {}) -> index
582
818
  *
583
- * :type ::
584
- * A Symbol denoting the object's type. Possible values are:
585
- * +:tree+, +:blob+, +:commit+ or +:tag+.
586
- * :len ::
587
- * A Number representing the object's length, in bytes.
819
+ * Reverts the given commit against the given "our" commit, producing an
820
+ * index that reflects the result of the revert.
588
821
  */
589
- static VALUE rb_git_repo_read_header(VALUE self, VALUE hex)
822
+ static VALUE rb_git_repo_revert_commit(int argc, VALUE *argv, VALUE self)
590
823
  {
824
+ VALUE rb_revert_commit, rb_our_commit, rb_options;
825
+ git_commit *revert_commit, *our_commit;
826
+ git_index *index;
591
827
  git_repository *repo;
592
- git_oid oid;
593
- git_odb *odb;
594
- git_otype type;
595
- size_t len;
596
- VALUE rb_hash;
828
+ git_merge_options opts = GIT_MERGE_OPTIONS_INIT;
829
+ unsigned int mainline = 0;
597
830
  int error;
598
831
 
599
- Data_Get_Struct(self, git_repository, repo);
600
- Check_Type(hex, T_STRING);
832
+ rb_scan_args(argc, argv, "20:", &rb_revert_commit, &rb_our_commit, &rb_options);
601
833
 
602
- error = git_oid_fromstr(&oid, StringValueCStr(hex));
603
- rugged_exception_check(error);
834
+ if (TYPE(rb_revert_commit) == T_STRING)
835
+ rb_revert_commit = rugged_object_rev_parse(self, rb_revert_commit, 1);
604
836
 
605
- error = git_repository_odb(&odb, repo);
606
- rugged_exception_check(error);
837
+ if (TYPE(rb_our_commit) == T_STRING)
838
+ rb_our_commit = rugged_object_rev_parse(self, rb_our_commit, 1);
607
839
 
608
- error = git_odb_read_header(&len, &type, odb, &oid);
609
- git_odb_free(odb);
610
- rugged_exception_check(error);
840
+ if (!rb_obj_is_kind_of(rb_revert_commit, rb_cRuggedCommit) ||
841
+ !rb_obj_is_kind_of(rb_our_commit, rb_cRuggedCommit)) {
842
+ rb_raise(rb_eArgError, "Expected a Rugged::Commit.");
843
+ }
611
844
 
612
- rb_hash = rb_hash_new();
613
- rb_hash_aset(rb_hash, CSTR2SYM("type"), CSTR2SYM(git_object_type2string(type)));
614
- rb_hash_aset(rb_hash, CSTR2SYM("len"), INT2FIX(len));
845
+ if (!NIL_P(rb_options)) {
846
+ VALUE rb_mainline;
615
847
 
616
- return rb_hash;
848
+ Check_Type(rb_options, T_HASH);
849
+ rugged_parse_merge_options(&opts, rb_options);
850
+
851
+ rb_mainline = rb_hash_aref(rb_options, CSTR2SYM("mainline"));
852
+ if (!NIL_P(rb_mainline)) {
853
+ Check_Type(rb_mainline, T_FIXNUM);
854
+ mainline = FIX2UINT(rb_mainline);
855
+ }
856
+ }
857
+
858
+ Data_Get_Struct(self, git_repository, repo);
859
+ Data_Get_Struct(rb_revert_commit, git_commit, revert_commit);
860
+ Data_Get_Struct(rb_our_commit, git_commit, our_commit);
861
+
862
+ error = git_revert_commit(&index, repo, revert_commit, our_commit, mainline, &opts);
863
+ if (error == GIT_EMERGECONFLICT)
864
+ return Qnil;
865
+
866
+ rugged_exception_check(error);
867
+
868
+ return rugged_index_new(rb_cRuggedIndex, self, index);
617
869
  }
618
870
 
619
871
  /*
620
872
  * call-seq:
621
- * Repository.hash(buffer, type) -> oid
622
- *
623
- * Hash the contents of +buffer+ as raw bytes (ignoring any encoding
624
- * information) and adding the relevant header corresponding to +type+,
625
- * and return a hex string representing the result from the hash.
873
+ * repo.merge_commits(our_commit, their_commit, options = {}) -> index
626
874
  *
627
- * Repository.hash('hello world', :commit) #=> "de5ba987198bcf2518885f0fc1350e5172cded78"
875
+ * Merges the two given commits, returning a Rugged::Index that reflects
876
+ * the result of the merge.
628
877
  *
629
- * Repository.hash('hello_world', :tag) #=> "9d09060c850defbc7711d08b57def0d14e742f4e"
878
+ * +our_commit+ and +their_commit+ can either be Rugged::Commit objects,
879
+ * or OIDs resolving to the former.
630
880
  */
631
- static VALUE rb_git_repo_hash(VALUE self, VALUE rb_buffer, VALUE rb_type)
881
+ static VALUE rb_git_repo_merge_commits(int argc, VALUE *argv, VALUE self)
632
882
  {
883
+ VALUE rb_our_commit, rb_their_commit, rb_options;
884
+ git_commit *our_commit, *their_commit;
885
+ git_index *index;
886
+ git_repository *repo;
887
+ git_merge_options opts = GIT_MERGE_OPTIONS_INIT;
633
888
  int error;
634
- git_oid oid;
635
889
 
636
- Check_Type(rb_buffer, T_STRING);
890
+ rb_scan_args(argc, argv, "20:", &rb_our_commit, &rb_their_commit, &rb_options);
637
891
 
638
- error = git_odb_hash(&oid,
639
- RSTRING_PTR(rb_buffer),
640
- RSTRING_LEN(rb_buffer),
641
- rugged_otype_get(rb_type)
642
- );
643
- rugged_exception_check(error);
892
+ if (TYPE(rb_our_commit) == T_STRING) {
893
+ rb_our_commit = rugged_object_rev_parse(self, rb_our_commit, 1);
894
+ }
644
895
 
645
- return rugged_create_oid(&oid);
646
- }
896
+ if (!rb_obj_is_kind_of(rb_our_commit, rb_cRuggedCommit)) {
897
+ rb_raise(rb_eArgError, "Expected a Rugged::Commit.");
898
+ }
647
899
 
648
- /*
649
- * call-seq:
900
+ if (TYPE(rb_their_commit) == T_STRING) {
901
+ rb_their_commit = rugged_object_rev_parse(self, rb_their_commit, 1);
902
+ }
903
+
904
+ if (!rb_obj_is_kind_of(rb_their_commit, rb_cRuggedCommit)) {
905
+ rb_raise(rb_eArgError, "Expected a Rugged::Commit.");
906
+ }
907
+
908
+ if (!NIL_P(rb_options)) {
909
+ Check_Type(rb_options, T_HASH);
910
+ rugged_parse_merge_options(&opts, rb_options);
911
+ }
912
+
913
+ Data_Get_Struct(self, git_repository, repo);
914
+ Data_Get_Struct(rb_our_commit, git_commit, our_commit);
915
+ Data_Get_Struct(rb_their_commit, git_commit, their_commit);
916
+
917
+ error = git_merge_commits(&index, repo, our_commit, their_commit, &opts);
918
+ if (error == GIT_EMERGECONFLICT)
919
+ return Qnil;
920
+
921
+ rugged_exception_check(error);
922
+
923
+ return rugged_index_new(rb_cRuggedIndex, self, index);
924
+ }
925
+
926
+ /*
927
+ * call-seq:
928
+ * repo.include?(oid) -> true or false
929
+ * repo.exists?(oid) -> true or false
930
+ *
931
+ * Return whether an object with the given SHA1 OID (represented as
932
+ * a hex string of at least 7 characters) exists in the repository.
933
+ *
934
+ * repo.include?("d8786bfc97485e8d7b19b21fb88c8ef1f199fc3f") #=> true
935
+ * repo.include?("d8786bfc") #=> true
936
+ */
937
+ static VALUE rb_git_repo_exists(VALUE self, VALUE hex)
938
+ {
939
+ git_repository *repo;
940
+ git_odb *odb;
941
+ git_oid oid;
942
+ int error;
943
+
944
+ Data_Get_Struct(self, git_repository, repo);
945
+ Check_Type(hex, T_STRING);
946
+
947
+ error = git_oid_fromstrn(&oid, RSTRING_PTR(hex), RSTRING_LEN(hex));
948
+ rugged_exception_check(error);
949
+
950
+ error = git_repository_odb(&odb, repo);
951
+ rugged_exception_check(error);
952
+
953
+ error = git_odb_exists_prefix(NULL, odb, &oid, RSTRING_LEN(hex));
954
+ git_odb_free(odb);
955
+
956
+ if (error == 0 || error == GIT_EAMBIGUOUS)
957
+ return Qtrue;
958
+
959
+ return Qfalse;
960
+ }
961
+
962
+ /*
963
+ * call-seq:
964
+ * repo.read(oid) -> str
965
+ *
966
+ * Read and return the raw data of the object identified by the given +oid+.
967
+ */
968
+ static VALUE rb_git_repo_read(VALUE self, VALUE hex)
969
+ {
970
+ git_repository *repo;
971
+ git_oid oid;
972
+ int error;
973
+
974
+ Data_Get_Struct(self, git_repository, repo);
975
+ Check_Type(hex, T_STRING);
976
+
977
+ error = git_oid_fromstr(&oid, StringValueCStr(hex));
978
+ rugged_exception_check(error);
979
+
980
+ return rugged_raw_read(repo, &oid);
981
+ }
982
+
983
+ /*
984
+ * call-seq:
985
+ * repo.read_header(oid) -> hash
986
+ *
987
+ * Read and return the header information in +repo+'s ODB
988
+ * for the object identified by the given +oid+.
989
+ *
990
+ * Returns a Hash object with the following key/value pairs:
991
+ *
992
+ * :type ::
993
+ * A Symbol denoting the object's type. Possible values are:
994
+ * +:tree+, +:blob+, +:commit+ or +:tag+.
995
+ * :len ::
996
+ * A Number representing the object's length, in bytes.
997
+ */
998
+ static VALUE rb_git_repo_read_header(VALUE self, VALUE hex)
999
+ {
1000
+ git_repository *repo;
1001
+ git_oid oid;
1002
+ git_odb *odb;
1003
+ git_otype type;
1004
+ size_t len;
1005
+ VALUE rb_hash;
1006
+ int error;
1007
+
1008
+ Data_Get_Struct(self, git_repository, repo);
1009
+ Check_Type(hex, T_STRING);
1010
+
1011
+ error = git_oid_fromstr(&oid, StringValueCStr(hex));
1012
+ rugged_exception_check(error);
1013
+
1014
+ error = git_repository_odb(&odb, repo);
1015
+ rugged_exception_check(error);
1016
+
1017
+ error = git_odb_read_header(&len, &type, odb, &oid);
1018
+ git_odb_free(odb);
1019
+ rugged_exception_check(error);
1020
+
1021
+ rb_hash = rb_hash_new();
1022
+ rb_hash_aset(rb_hash, CSTR2SYM("type"), CSTR2SYM(git_object_type2string(type)));
1023
+ rb_hash_aset(rb_hash, CSTR2SYM("len"), INT2FIX(len));
1024
+
1025
+ return rb_hash;
1026
+ }
1027
+
1028
+ /**
1029
+ * call-seq:
1030
+ * repo.expand_oids([oid..], object_type = :any) -> hash
1031
+ * repo.expand_oids([oid..], object_type = [type..]) -> hash
1032
+ *
1033
+ * Expand a list of short oids to their full value, assuming they exist
1034
+ * in the repository. If `object_type` is passed and is an array, it must
1035
+ * be the same length as the OIDs array. If it's a single type name, all
1036
+ * OIDs will be expected to resolve to that object type. OIDs that don't
1037
+ * match the expected object types will not be expanded.
1038
+ *
1039
+ * Returns a hash of `{ short_oid => full_oid }` for the short OIDs which
1040
+ * exist in the repository and match the expected object type. Missing OIDs
1041
+ * will not appear in the resulting hash.
1042
+ */
1043
+ static VALUE rb_git_repo_expand_oids(int argc, VALUE *argv, VALUE self)
1044
+ {
1045
+ VALUE rb_result, rb_oids, rb_expected_type;
1046
+
1047
+ git_repository *repo;
1048
+ git_odb *odb;
1049
+ git_odb_expand_id *expand;
1050
+ long i, expand_count;
1051
+ int error;
1052
+
1053
+ Data_Get_Struct(self, git_repository, repo);
1054
+ rb_scan_args(argc, argv, "11", &rb_oids, &rb_expected_type);
1055
+
1056
+ Check_Type(rb_oids, T_ARRAY);
1057
+ expand_count = RARRAY_LEN(rb_oids);
1058
+ expand = alloca(expand_count * sizeof(git_odb_expand_id));
1059
+
1060
+ for (i = 0; i < expand_count; ++i) {
1061
+ VALUE rb_hex = rb_ary_entry(rb_oids, i);
1062
+ Check_Type(rb_hex, T_STRING);
1063
+
1064
+ rugged_exception_check(
1065
+ git_oid_fromstrn(&expand[i].id, RSTRING_PTR(rb_hex), RSTRING_LEN(rb_hex))
1066
+ );
1067
+ expand[i].length = RSTRING_LEN(rb_hex);
1068
+ }
1069
+
1070
+ if (TYPE(rb_expected_type) == T_ARRAY) {
1071
+ if (RARRAY_LEN(rb_expected_type) != expand_count)
1072
+ rb_raise(rb_eRuntimeError,
1073
+ "the `object_type` array must be the same length as the `oids` array");
1074
+
1075
+ for (i = 0; i < expand_count; ++i) {
1076
+ VALUE rb_type = rb_ary_entry(rb_expected_type, i);
1077
+ expand[i].type = rugged_otype_get(rb_type);
1078
+ }
1079
+ } else {
1080
+ git_otype expected_type = GIT_OBJ_ANY;
1081
+
1082
+ if (!NIL_P(rb_expected_type))
1083
+ expected_type = rugged_otype_get(rb_expected_type);
1084
+
1085
+ for (i = 0; i < expand_count; ++i)
1086
+ expand[i].type = expected_type;
1087
+ }
1088
+
1089
+ error = git_repository_odb(&odb, repo);
1090
+ rugged_exception_check(error);
1091
+
1092
+ error = git_odb_expand_ids(odb, expand, (size_t)expand_count);
1093
+ git_odb_free(odb);
1094
+ rugged_exception_check(error);
1095
+
1096
+ rb_result = rb_hash_new();
1097
+
1098
+ for (i = 0; i < expand_count; ++i) {
1099
+ if (expand[i].length) {
1100
+ rb_hash_aset(rb_result,
1101
+ rb_ary_entry(rb_oids, i), rugged_create_oid(&expand[i].id));
1102
+ }
1103
+ }
1104
+
1105
+ return rb_result;
1106
+ }
1107
+
1108
+ /*
1109
+ * call-seq:
1110
+ * repo.descendant_of?(commit, ancestor) -> true or false
1111
+ *
1112
+ * +commit+ and +ancestor+ must be String commit OIDs or instances of Rugged::Commit.
1113
+ *
1114
+ * Returns true if +commit+ is a descendant of +ancestor+, or false if not.
1115
+ */
1116
+ static VALUE rb_git_repo_descendant_of(VALUE self, VALUE rb_commit, VALUE rb_ancestor)
1117
+ {
1118
+ int result;
1119
+ int error;
1120
+ git_repository *repo;
1121
+ git_oid commit, ancestor;
1122
+
1123
+ Data_Get_Struct(self, git_repository, repo);
1124
+
1125
+ error = rugged_oid_get(&commit, repo, rb_commit);
1126
+ rugged_exception_check(error);
1127
+
1128
+ error = rugged_oid_get(&ancestor, repo, rb_ancestor);
1129
+ rugged_exception_check(error);
1130
+
1131
+ result = git_graph_descendant_of(repo, &commit, &ancestor);
1132
+ rugged_exception_check(result);
1133
+
1134
+ return result ? Qtrue : Qfalse;
1135
+ }
1136
+
1137
+ /*
1138
+ * call-seq:
1139
+ * Repository.hash_data(str, type) -> oid
1140
+ *
1141
+ * Hash the contents of +str+ as raw bytes (ignoring any encoding
1142
+ * information) and adding the relevant header corresponding to +type+,
1143
+ * and return a hex string representing the result from the hash.
1144
+ *
1145
+ * Repository.hash_data('hello world', :commit) #=> "de5ba987198bcf2518885f0fc1350e5172cded78"
1146
+ *
1147
+ * Repository.hash_data('hello_world', :tag) #=> "9d09060c850defbc7711d08b57def0d14e742f4e"
1148
+ */
1149
+ static VALUE rb_git_repo_hash(VALUE self, VALUE rb_buffer, VALUE rb_type)
1150
+ {
1151
+ int error;
1152
+ git_oid oid;
1153
+
1154
+ Check_Type(rb_buffer, T_STRING);
1155
+
1156
+ error = git_odb_hash(&oid,
1157
+ RSTRING_PTR(rb_buffer),
1158
+ RSTRING_LEN(rb_buffer),
1159
+ rugged_otype_get(rb_type)
1160
+ );
1161
+ rugged_exception_check(error);
1162
+
1163
+ return rugged_create_oid(&oid);
1164
+ }
1165
+
1166
+ /*
1167
+ * call-seq:
650
1168
  * Repository.hash_file(path, type) -> oid
651
1169
  *
652
1170
  * Hash the contents of the file pointed at by +path+, assuming
@@ -662,7 +1180,7 @@ static VALUE rb_git_repo_hashfile(VALUE self, VALUE rb_path, VALUE rb_type)
662
1180
  int error;
663
1181
  git_oid oid;
664
1182
 
665
- Check_Type(rb_path, T_STRING);
1183
+ FilePathValue(rb_path);
666
1184
 
667
1185
  error = git_odb_hashfile(&oid,
668
1186
  StringValueCStr(rb_path),
@@ -707,11 +1225,11 @@ static VALUE rb_git_repo_write(VALUE self, VALUE rb_buffer, VALUE rub_type)
707
1225
  git_odb_free(odb);
708
1226
  rugged_exception_check(error);
709
1227
 
710
- error = stream->write(stream, RSTRING_PTR(rb_buffer), RSTRING_LEN(rb_buffer));
1228
+ error = git_odb_stream_write(stream, RSTRING_PTR(rb_buffer), RSTRING_LEN(rb_buffer));
711
1229
  if (!error)
712
- error = stream->finalize_write(&oid, stream);
1230
+ error = git_odb_stream_finalize_write(&oid, stream);
713
1231
 
714
- stream->free(stream);
1232
+ git_odb_stream_free(stream);
715
1233
  rugged_exception_check(error);
716
1234
 
717
1235
  return rugged_create_oid(&oid);
@@ -737,6 +1255,18 @@ static VALUE rb_git_repo_is_bare(VALUE self)
737
1255
  RB_GIT_REPO_GETTER(is_bare);
738
1256
  }
739
1257
 
1258
+ /*
1259
+ * call-seq:
1260
+ * repo.shallow? -> true or false
1261
+ *
1262
+ * Return whether a repository is a shallow clone or not. A shallow clone has
1263
+ * a truncated history and can not be cloned or fetched from, nor can be
1264
+ * pushed from nor into it.
1265
+ */
1266
+ static VALUE rb_git_repo_is_shallow(VALUE self)
1267
+ {
1268
+ RB_GIT_REPO_GETTER(is_shallow);
1269
+ }
740
1270
 
741
1271
  /*
742
1272
  * call-seq:
@@ -763,13 +1293,14 @@ static VALUE rb_git_repo_head_detached(VALUE self)
763
1293
 
764
1294
  /*
765
1295
  * call-seq:
766
- * repo.head_orphan? -> true or false
1296
+ * repo.head_unborn? -> true or false
767
1297
  *
768
- * Return whether the +HEAD+ of a repository is orphaned or not.
1298
+ * Return whether the current branch is unborn (+HEAD+ points to a
1299
+ * non-existent branch).
769
1300
  */
770
- static VALUE rb_git_repo_head_orphan(VALUE self)
1301
+ static VALUE rb_git_repo_head_unborn(VALUE self)
771
1302
  {
772
- RB_GIT_REPO_GETTER(head_orphan);
1303
+ RB_GIT_REPO_GETTER(head_unborn);
773
1304
  }
774
1305
 
775
1306
  /*
@@ -829,8 +1360,12 @@ static VALUE rb_git_repo_get_head(VALUE self)
829
1360
  static VALUE rb_git_repo_path(VALUE self)
830
1361
  {
831
1362
  git_repository *repo;
1363
+ const char *path;
1364
+
832
1365
  Data_Get_Struct(self, git_repository, repo);
833
- return rb_str_new_utf8(git_repository_path(repo));
1366
+ path = git_repository_path(repo);
1367
+
1368
+ return path ? rb_str_new_utf8(path) : Qnil;
834
1369
  }
835
1370
 
836
1371
  /*
@@ -902,10 +1437,11 @@ static VALUE rb_git_repo_set_workdir(VALUE self, VALUE rb_workdir)
902
1437
  * a different device than the one that contained +path+ (only applies
903
1438
  * to UNIX-based OSses).
904
1439
  */
905
- static VALUE rb_git_repo_discover(int argc, VALUE *argv, VALUE self)
1440
+ static VALUE rb_git_repo_discover(int argc, VALUE *argv, VALUE klass)
906
1441
  {
1442
+ git_repository *repo;
907
1443
  VALUE rb_path, rb_across_fs;
908
- char repository_path[GIT_PATH_MAX];
1444
+ git_buf repository_path = { NULL };
909
1445
  int error, across_fs = 0;
910
1446
 
911
1447
  rb_scan_args(argc, argv, "02", &rb_path, &rb_across_fs);
@@ -919,17 +1455,23 @@ static VALUE rb_git_repo_discover(int argc, VALUE *argv, VALUE self)
919
1455
  across_fs = rugged_parse_bool(rb_across_fs);
920
1456
  }
921
1457
 
922
- Check_Type(rb_path, T_STRING);
1458
+ FilePathValue(rb_path);
923
1459
 
924
1460
  error = git_repository_discover(
925
- repository_path, GIT_PATH_MAX,
1461
+ &repository_path,
926
1462
  StringValueCStr(rb_path),
927
1463
  across_fs,
928
1464
  NULL
929
1465
  );
930
1466
 
931
1467
  rugged_exception_check(error);
932
- return rb_str_new_utf8(repository_path);
1468
+
1469
+ error = git_repository_open(&repo, repository_path.ptr);
1470
+ git_buf_dispose(&repository_path);
1471
+
1472
+ rugged_exception_check(error);
1473
+
1474
+ return rugged_repo_new(klass, repo);
933
1475
  }
934
1476
 
935
1477
  static VALUE flags_to_rb(unsigned int flags)
@@ -954,6 +1496,9 @@ static VALUE flags_to_rb(unsigned int flags)
954
1496
  if (flags & GIT_STATUS_WT_DELETED)
955
1497
  rb_ary_push(rb_flags, CSTR2SYM("worktree_deleted"));
956
1498
 
1499
+ if (flags & GIT_STATUS_IGNORED)
1500
+ rb_ary_push(rb_flags, CSTR2SYM("ignored"));
1501
+
957
1502
  return rb_flags;
958
1503
  }
959
1504
 
@@ -966,58 +1511,26 @@ static int rugged__status_cb(const char *path, unsigned int flags, void *payload
966
1511
  return GIT_OK;
967
1512
  }
968
1513
 
969
- /*
970
- * call-seq:
971
- * repo.status { |status_data| block }
972
- * repo.status(path) -> status_data
973
- *
974
- * Returns the status for one or more files in the working directory
975
- * of the repository. This is equivalent to the +git status+ command.
976
- *
977
- * The returned +status_data+ is always an array containing one or more
978
- * status flags as Ruby symbols. Possible flags are:
979
- *
980
- * - +:index_new+: the file is new in the index
981
- * - +:index_modified+: the file has been modified in the index
982
- * - +:index_deleted+: the file has been deleted from the index
983
- * - +:worktree_new+: the file is new in the working directory
984
- * - +:worktree_modified+: the file has been modified in the working directory
985
- * - +:worktree_deleted+: the file has been deleted from the working directory
986
- *
987
- * If a +block+ is given, status information will be gathered for every
988
- * single file on the working dir. The +block+ will be called with the
989
- * status data for each file.
990
- *
991
- * repo.status { |status_data| puts status_data.inspect }
992
- *
993
- * results in, for example:
994
- *
995
- * [:index_new, :worktree_new]
996
- * [:worktree_modified]
997
- *
998
- * If a +path+ is given instead, the function will return the +status_data+ for
999
- * the file pointed to by path, or raise an exception if the path doesn't exist.
1000
- *
1001
- * +path+ must be relative to the repository's working directory.
1002
- *
1003
- * repo.status('src/diff.c') #=> [:index_new, :worktree_new]
1004
- */
1005
- static VALUE rb_git_repo_status(int argc, VALUE *argv, VALUE self)
1514
+ static VALUE rb_git_repo_file_status(VALUE self, VALUE rb_path)
1006
1515
  {
1516
+ unsigned int flags;
1007
1517
  int error;
1008
- VALUE rb_path;
1009
1518
  git_repository *repo;
1010
1519
 
1011
1520
  Data_Get_Struct(self, git_repository, repo);
1521
+ FilePathValue(rb_path);
1522
+ error = git_status_file(&flags, repo, StringValueCStr(rb_path));
1523
+ rugged_exception_check(error);
1012
1524
 
1013
- if (rb_scan_args(argc, argv, "01", &rb_path) == 1) {
1014
- unsigned int flags;
1015
- Check_Type(rb_path, T_STRING);
1016
- error = git_status_file(&flags, repo, StringValueCStr(rb_path));
1017
- rugged_exception_check(error);
1525
+ return flags_to_rb(flags);
1526
+ }
1018
1527
 
1019
- return flags_to_rb(flags);
1020
- }
1528
+ static VALUE rb_git_repo_file_each_status(VALUE self)
1529
+ {
1530
+ int error;
1531
+ git_repository *repo;
1532
+
1533
+ Data_Get_Struct(self, git_repository, repo);
1021
1534
 
1022
1535
  if (!rb_block_given_p())
1023
1536
  rb_raise(rb_eRuntimeError,
@@ -1044,7 +1557,7 @@ static int rugged__each_id_cb(const git_oid *id, void *payload)
1044
1557
  /*
1045
1558
  * call-seq:
1046
1559
  * repo.each_id { |id| block }
1047
- * repo.each_id -> Iterator
1560
+ * repo.each_id -> Enumerator
1048
1561
  *
1049
1562
  * Call the given +block+ once with every object ID found in +repo+
1050
1563
  * and all its alternates. Object IDs are passed as 40-character
@@ -1056,8 +1569,7 @@ static VALUE rb_git_repo_each_id(VALUE self)
1056
1569
  git_odb *odb;
1057
1570
  int error, exception = 0;
1058
1571
 
1059
- if (!rb_block_given_p())
1060
- return rb_funcall(self, rb_intern("to_enum"), 1, CSTR2SYM("each_id"));
1572
+ RETURN_ENUMERATOR(self, 0, 0);
1061
1573
 
1062
1574
  Data_Get_Struct(self, git_repository, repo);
1063
1575
 
@@ -1128,9 +1640,10 @@ static VALUE rb_git_repo_reset(VALUE self, VALUE rb_target, VALUE rb_reset_type)
1128
1640
  reset_type = parse_reset_type(rb_reset_type);
1129
1641
  target = rugged_object_get(repo, rb_target, GIT_OBJ_ANY);
1130
1642
 
1131
- error = git_reset(repo, target, reset_type);
1643
+ error = git_reset(repo, target, reset_type, NULL);
1132
1644
 
1133
1645
  git_object_free(target);
1646
+
1134
1647
  rugged_exception_check(error);
1135
1648
 
1136
1649
  return Qnil;
@@ -1158,8 +1671,7 @@ static VALUE rb_git_repo_reset_path(int argc, VALUE *argv, VALUE self)
1158
1671
  git_object *target = NULL;
1159
1672
  git_strarray pathspecs;
1160
1673
  VALUE rb_target, rb_paths;
1161
- VALUE rb_path_array;
1162
- int i, error = 0;
1674
+ int error = 0;
1163
1675
 
1164
1676
  pathspecs.strings = NULL;
1165
1677
  pathspecs.count = 0;
@@ -1168,18 +1680,7 @@ static VALUE rb_git_repo_reset_path(int argc, VALUE *argv, VALUE self)
1168
1680
 
1169
1681
  rb_scan_args(argc, argv, "11", &rb_paths, &rb_target);
1170
1682
 
1171
- rb_path_array = rb_ary_to_ary(rb_paths);
1172
-
1173
- for (i = 0; i < RARRAY_LEN(rb_path_array); ++i)
1174
- Check_Type(rb_ary_entry(rb_path_array, i), T_STRING);
1175
-
1176
- pathspecs.count = RARRAY_LEN(rb_path_array);
1177
- pathspecs.strings = xmalloc(pathspecs.count * sizeof(char *));
1178
-
1179
- for (i = 0; i < RARRAY_LEN(rb_path_array); ++i) {
1180
- VALUE fpath = rb_ary_entry(rb_path_array, i);
1181
- pathspecs.strings[i] = StringValueCStr(fpath);
1182
- }
1683
+ rugged_rb_ary_to_strarray(rb_paths, &pathspecs);
1183
1684
 
1184
1685
  if (!NIL_P(rb_target))
1185
1686
  target = rugged_object_get(repo, rb_target, GIT_OBJ_ANY);
@@ -1194,116 +1695,22 @@ static VALUE rb_git_repo_reset_path(int argc, VALUE *argv, VALUE self)
1194
1695
  return Qnil;
1195
1696
  }
1196
1697
 
1197
-
1198
- static int rugged__push_status_cb(const char *ref, const char *msg, void *payload)
1199
- {
1200
- VALUE rb_result_hash = (VALUE)payload;
1201
- if (msg != NULL)
1202
- rb_hash_aset(rb_result_hash, rb_str_new_utf8(ref), rb_str_new_utf8(msg));
1203
-
1204
- return GIT_OK;
1205
- }
1206
-
1207
1698
  /*
1208
1699
  * call-seq:
1209
- * repo.push(remote, refspecs) -> hash
1210
- *
1211
- * Pushes the given +refspecs+ to the given +remote+. Returns a hash that contains
1212
- * key-value pairs that reflect pushed refs and error messages, if applicable.
1700
+ * repo.close -> nil
1213
1701
  *
1214
- * Example:
1702
+ * Frees all the resources used by this repository immediately. The repository can
1703
+ * still be used after this call. Resources will be opened as necessary.
1215
1704
  *
1216
- * repo.push("origin", ["refs/heads/master", ":refs/heads/to_be_deleted"])
1705
+ * It is not required to call this method explicitly. Repositories are closed
1706
+ * automatically before garbage collection
1217
1707
  */
1218
- static VALUE rb_git_repo_push(VALUE self, VALUE rb_remote, VALUE rb_refspecs)
1708
+ static VALUE rb_git_repo_close(VALUE self)
1219
1709
  {
1220
- VALUE rb_refspec, rb_exception = Qnil, rb_result = rb_hash_new();
1221
1710
  git_repository *repo;
1222
- git_remote *remote = NULL;
1223
- git_push *push = NULL;
1224
-
1225
- int error = 0, i = 0;
1226
-
1227
- Check_Type(rb_refspecs, T_ARRAY);
1228
- for (i = 0; i < RARRAY_LEN(rb_refspecs); ++i) {
1229
- rb_refspec = rb_ary_entry(rb_refspecs, i);
1230
- Check_Type(rb_refspec, T_STRING);
1231
- }
1232
-
1233
1711
  Data_Get_Struct(self, git_repository, repo);
1234
1712
 
1235
- if (rb_obj_is_kind_of(rb_remote, rb_cRuggedRemote)) {
1236
- Data_Get_Struct(rb_remote, git_remote, remote);
1237
- } else if (TYPE(rb_remote) == T_STRING) {
1238
- error = git_remote_load(&remote, repo, StringValueCStr(rb_remote));
1239
- if (error) goto cleanup;
1240
- } else {
1241
- rb_raise(rb_eTypeError, "Expecting a String or Rugged::Remote instance");
1242
- }
1243
-
1244
- error = git_push_new(&push, remote);
1245
- if (error) goto cleanup;
1246
-
1247
- for (i = 0; !error && i < RARRAY_LEN(rb_refspecs); ++i) {
1248
- rb_refspec = rb_ary_entry(rb_refspecs, i);
1249
- error = git_push_add_refspec(push, StringValueCStr(rb_refspec));
1250
- }
1251
- if (error) goto cleanup;
1252
-
1253
- error = git_push_finish(push);
1254
-
1255
- if (error) {
1256
- if (error == GIT_ENONFASTFORWARD) {
1257
- rb_exception = rb_exc_new2(rb_eRuggedError, "non-fast-forward update rejected");
1258
- } else if (error == -1) {
1259
- rb_exception = rb_exc_new2(rb_eRuggedError, "could not push to repo (check for non-bare repo)");
1260
- }
1261
-
1262
- goto cleanup;
1263
- }
1264
-
1265
- if (!git_push_unpack_ok(push)) {
1266
- rb_exception = rb_exc_new2(rb_eRuggedError, "the remote side did not unpack successfully");
1267
- goto cleanup;
1268
- }
1269
-
1270
- error = git_push_status_foreach(push, &rugged__push_status_cb, (void *)rb_result);
1271
- if (error) goto cleanup;
1272
-
1273
- error = git_push_update_tips(push);
1274
-
1275
- cleanup:
1276
- git_push_free(push);
1277
-
1278
- // We can only free the remote if we have loaded it ourselves.
1279
- if (!rb_obj_is_kind_of(rb_remote, rb_cRuggedRemote)) {
1280
- git_remote_free(remote);
1281
- }
1282
-
1283
- if (!NIL_P(rb_exception))
1284
- rb_exc_raise(rb_exception);
1285
-
1286
- rugged_exception_check(error);
1287
-
1288
- return rb_result;
1289
- }
1290
-
1291
- /*
1292
- * call-seq:
1293
- * repo.close -> nil
1294
- *
1295
- * Frees all the resources used by this repository immediately. The repository can
1296
- * still be used after this call. Resources will be opened as necessary.
1297
- *
1298
- * It is not required to call this method explicitly. Repositories are closed
1299
- * automatically before garbage collection
1300
- */
1301
- static VALUE rb_git_repo_close(VALUE self)
1302
- {
1303
- git_repository *repo;
1304
- Data_Get_Struct(self, git_repository, repo);
1305
-
1306
- git_repository__cleanup(repo);
1713
+ git_repository__cleanup(repo);
1307
1714
 
1308
1715
  return Qnil;
1309
1716
  }
@@ -1384,6 +1791,758 @@ static VALUE rb_git_repo_ahead_behind(VALUE self, VALUE rb_local, VALUE rb_upstr
1384
1791
  return rb_result;
1385
1792
  }
1386
1793
 
1794
+ /*
1795
+ * call-seq:
1796
+ * repo.default_signature -> signature or nil
1797
+ *
1798
+ * Returns a +Hash+ with the default user +signature+ or +nil+.
1799
+ *
1800
+ * Looks up the +user.name+ and +user.email+ from the configuration and
1801
+ * uses the current time as the timestamp, and creates a new signature
1802
+ * based on that information. It will return +nil+ if either the
1803
+ * +user.name+ or +user.email+ are not set.
1804
+ *
1805
+ * Returns a +Hash+:
1806
+ * - +:name+: the +user.name+ config value
1807
+ * - +:email+: the +user.email+ config value
1808
+ * - +:time+: the current time as a +Time+ instance
1809
+ */
1810
+ static VALUE rb_git_repo_default_signature(VALUE self) {
1811
+ int error;
1812
+ git_repository *repo;
1813
+ git_signature *signature;
1814
+ VALUE rb_signature;
1815
+
1816
+ Data_Get_Struct(self, git_repository, repo);
1817
+
1818
+ error = git_signature_default(&signature, repo);
1819
+
1820
+ if (error == GIT_ENOTFOUND)
1821
+ return Qnil;
1822
+
1823
+ rugged_exception_check(error);
1824
+
1825
+ rb_signature = rugged_signature_new(signature, NULL);
1826
+ git_signature_free(signature);
1827
+ return rb_signature;
1828
+ }
1829
+
1830
+ void rugged__checkout_progress_cb(
1831
+ const char *path,
1832
+ size_t completed_steps,
1833
+ size_t total_steps,
1834
+ void *data
1835
+ ) {
1836
+ struct rugged_cb_payload *payload = data;
1837
+ VALUE args = rb_ary_new2(4);
1838
+ rb_ary_push(args, payload->rb_data);
1839
+ rb_ary_push(args, path == NULL ? Qnil : rb_str_new2(path));
1840
+ rb_ary_push(args, INT2FIX(completed_steps));
1841
+ rb_ary_push(args, INT2FIX(total_steps));
1842
+
1843
+ rb_protect(rugged__block_yield_splat, args, &payload->exception);
1844
+ }
1845
+
1846
+ static int rugged__checkout_notify_cb(
1847
+ git_checkout_notify_t why,
1848
+ const char *path,
1849
+ const git_diff_file *baseline,
1850
+ const git_diff_file *target,
1851
+ const git_diff_file *workdir,
1852
+ void *data
1853
+ ) {
1854
+ struct rugged_cb_payload *payload = data;
1855
+ VALUE args = rb_ary_new2(5);
1856
+ rb_ary_push(args, payload->rb_data);
1857
+
1858
+ switch (why) {
1859
+ case GIT_CHECKOUT_NOTIFY_CONFLICT:
1860
+ rb_ary_push(args, CSTR2SYM("conflict"));
1861
+ break;
1862
+
1863
+ case GIT_CHECKOUT_NOTIFY_DIRTY:
1864
+ rb_ary_push(args, CSTR2SYM("dirty"));
1865
+ break;
1866
+
1867
+ case GIT_CHECKOUT_NOTIFY_UPDATED:
1868
+ rb_ary_push(args, CSTR2SYM("updated"));
1869
+ break;
1870
+
1871
+ case GIT_CHECKOUT_NOTIFY_UNTRACKED:
1872
+ rb_ary_push(args, CSTR2SYM("untracked"));
1873
+ break;
1874
+
1875
+ case GIT_CHECKOUT_NOTIFY_IGNORED:
1876
+ rb_ary_push(args, CSTR2SYM("ignored"));
1877
+ break;
1878
+
1879
+ default:
1880
+ rb_ary_push(args, CSTR2SYM("unknown"));
1881
+ }
1882
+
1883
+ rb_ary_push(args, rb_git_delta_file_fromC(baseline));
1884
+ rb_ary_push(args, rb_git_delta_file_fromC(target));
1885
+ rb_ary_push(args, rb_git_delta_file_fromC(workdir));
1886
+
1887
+ rb_protect(rugged__block_yield_splat, args, &payload->exception);
1888
+
1889
+ return payload->exception ? GIT_ERROR : GIT_OK;
1890
+ }
1891
+
1892
+ /**
1893
+ * The caller has to free the returned git_checkout_options paths strings array.
1894
+ */
1895
+ void rugged_parse_checkout_options(git_checkout_options *opts, VALUE rb_options)
1896
+ {
1897
+ VALUE rb_value;
1898
+
1899
+ if (NIL_P(rb_options))
1900
+ return;
1901
+
1902
+ Check_Type(rb_options, T_HASH);
1903
+
1904
+ rb_value = rb_hash_aref(rb_options, CSTR2SYM("progress"));
1905
+ if (!NIL_P(rb_value)) {
1906
+ struct rugged_cb_payload *payload = xmalloc(sizeof(struct rugged_cb_payload));
1907
+ payload->rb_data = rb_value;
1908
+ payload->exception = 0;
1909
+
1910
+ opts->progress_payload = payload;
1911
+ opts->progress_cb = &rugged__checkout_progress_cb;
1912
+ }
1913
+
1914
+ rb_value = rb_hash_aref(rb_options, CSTR2SYM("notify"));
1915
+ if (!NIL_P(rb_value)) {
1916
+ struct rugged_cb_payload *payload = xmalloc(sizeof(struct rugged_cb_payload));
1917
+ payload->rb_data = rb_value;
1918
+ payload->exception = 0;
1919
+
1920
+ opts->notify_payload = payload;
1921
+ opts->notify_cb = &rugged__checkout_notify_cb;
1922
+ }
1923
+
1924
+ if (!NIL_P(rb_value = rb_hash_aref(rb_options, CSTR2SYM("strategy")))) {
1925
+ int i;
1926
+
1927
+ rb_value = rb_ary_to_ary(rb_value);
1928
+ for (i = 0; i < RARRAY_LEN(rb_value); ++i) {
1929
+ VALUE rb_strategy = rb_ary_entry(rb_value, i);
1930
+
1931
+ if (rb_strategy == CSTR2SYM("safe")) {
1932
+ opts->checkout_strategy |= GIT_CHECKOUT_SAFE;
1933
+ } else if (rb_strategy == CSTR2SYM("force")) {
1934
+ opts->checkout_strategy |= GIT_CHECKOUT_FORCE;
1935
+ } else if (rb_strategy == CSTR2SYM("recreate_missing")) {
1936
+ opts->checkout_strategy |= GIT_CHECKOUT_RECREATE_MISSING;
1937
+ } else if (rb_strategy == CSTR2SYM("allow_conflicts")) {
1938
+ opts->checkout_strategy |= GIT_CHECKOUT_ALLOW_CONFLICTS;
1939
+ } else if (rb_strategy == CSTR2SYM("remove_untracked")) {
1940
+ opts->checkout_strategy |= GIT_CHECKOUT_REMOVE_UNTRACKED;
1941
+ } else if (rb_strategy == CSTR2SYM("remove_ignored")) {
1942
+ opts->checkout_strategy |= GIT_CHECKOUT_REMOVE_IGNORED;
1943
+ } else if (rb_strategy == CSTR2SYM("update_only")) {
1944
+ opts->checkout_strategy |= GIT_CHECKOUT_UPDATE_ONLY;
1945
+ } else if (rb_strategy == CSTR2SYM("dont_update_index")) {
1946
+ opts->checkout_strategy |= GIT_CHECKOUT_DONT_UPDATE_INDEX;
1947
+ } else if (rb_strategy == CSTR2SYM("no_refresh")) {
1948
+ opts->checkout_strategy |= GIT_CHECKOUT_NO_REFRESH;
1949
+ } else if (rb_strategy == CSTR2SYM("disable_pathspec_match")) {
1950
+ opts->checkout_strategy |= GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH;
1951
+ } else if (rb_strategy == CSTR2SYM("skip_locked_directories")) {
1952
+ opts->checkout_strategy |= GIT_CHECKOUT_SKIP_LOCKED_DIRECTORIES;
1953
+ } else if (rb_strategy == CSTR2SYM("skip_unmerged")) {
1954
+ opts->checkout_strategy |= GIT_CHECKOUT_SKIP_UNMERGED;
1955
+ } else if (rb_strategy == CSTR2SYM("use_ours")) {
1956
+ opts->checkout_strategy |= GIT_CHECKOUT_USE_OURS;
1957
+ } else if (rb_strategy == CSTR2SYM("use_theirs")) {
1958
+ opts->checkout_strategy |= GIT_CHECKOUT_USE_THEIRS;
1959
+ } else if (rb_strategy == CSTR2SYM("update_submodules")) {
1960
+ opts->checkout_strategy |= GIT_CHECKOUT_UPDATE_SUBMODULES;
1961
+ } else if (rb_strategy == CSTR2SYM("update_submodules_if_changed")) {
1962
+ opts->checkout_strategy |= GIT_CHECKOUT_UPDATE_SUBMODULES_IF_CHANGED;
1963
+ } else if (rb_strategy != CSTR2SYM("none")) {
1964
+ rb_raise(rb_eArgError, "Unknown checkout strategy");
1965
+ }
1966
+ }
1967
+ }
1968
+
1969
+ if (!NIL_P(rb_value = rb_hash_aref(rb_options, CSTR2SYM("notify_flags")))) {
1970
+ int i;
1971
+
1972
+ rb_value = rb_ary_to_ary(rb_value);
1973
+ for (i = 0; i < RARRAY_LEN(rb_value); ++i) {
1974
+ VALUE rb_notify_flag = rb_ary_entry(rb_value, i);
1975
+
1976
+ if (rb_notify_flag == CSTR2SYM("conflict")) {
1977
+ opts->notify_flags |= GIT_CHECKOUT_NOTIFY_CONFLICT;
1978
+ } else if (rb_notify_flag == CSTR2SYM("dirty")) {
1979
+ opts->notify_flags |= GIT_CHECKOUT_NOTIFY_DIRTY;
1980
+ } else if (rb_notify_flag == CSTR2SYM("updated")) {
1981
+ opts->notify_flags |= GIT_CHECKOUT_NOTIFY_UPDATED;
1982
+ } else if (rb_notify_flag == CSTR2SYM("untracked")) {
1983
+ opts->notify_flags |= GIT_CHECKOUT_NOTIFY_UNTRACKED;
1984
+ } else if (rb_notify_flag == CSTR2SYM("ignored")) {
1985
+ opts->notify_flags |= GIT_CHECKOUT_NOTIFY_IGNORED;
1986
+ } else if (rb_notify_flag == CSTR2SYM("all")) {
1987
+ opts->notify_flags |= GIT_CHECKOUT_NOTIFY_ALL;
1988
+ } else if (rb_notify_flag != CSTR2SYM("none")) {
1989
+ rb_raise(rb_eArgError, "Unknown checkout notify flag");
1990
+ }
1991
+ }
1992
+ }
1993
+
1994
+ opts->disable_filters = RTEST(rb_hash_aref(rb_options, CSTR2SYM("disable_filters")));
1995
+
1996
+ rb_value = rb_hash_aref(rb_options, CSTR2SYM("dir_mode"));
1997
+ if (!NIL_P(rb_value)) {
1998
+ opts->dir_mode = FIX2UINT(rb_value);
1999
+ }
2000
+
2001
+ rb_value = rb_hash_aref(rb_options, CSTR2SYM("file_mode"));
2002
+ if (!NIL_P(rb_value)) {
2003
+ opts->file_mode = FIX2UINT(rb_value);
2004
+ }
2005
+
2006
+ rb_value = rb_hash_aref(rb_options, CSTR2SYM("file_open_flags"));
2007
+ if (!NIL_P(rb_value)) {
2008
+ opts->file_mode = FIX2INT(rb_value);
2009
+ }
2010
+
2011
+ rb_value = rb_hash_aref(rb_options, CSTR2SYM("target_directory"));
2012
+ if (!NIL_P(rb_value)) {
2013
+ opts->target_directory = StringValueCStr(rb_value);
2014
+ }
2015
+
2016
+ rb_value = rb_hash_aref(rb_options, CSTR2SYM("baseline"));
2017
+ if (!NIL_P(rb_value)) {
2018
+ if (rb_obj_is_kind_of(rb_value, rb_cRuggedTree)) {
2019
+ Data_Get_Struct(rb_value, git_tree, opts->baseline);
2020
+ } else {
2021
+ rb_raise(rb_eTypeError, "Expected a Rugged::Tree.");
2022
+ }
2023
+ }
2024
+
2025
+ rb_value = rb_hash_aref(rb_options, CSTR2SYM("paths"));
2026
+ rugged_rb_ary_to_strarray(rb_value, &opts->paths);
2027
+ }
2028
+
2029
+ /**
2030
+ * call-seq:
2031
+ * repo.checkout_tree(treeish[, options])
2032
+ *
2033
+ * Updates files in the index and working tree to match the content of the
2034
+ * tree pointed at by the +treeish+.
2035
+ *
2036
+ * The following options can be passed in the +options+ Hash:
2037
+ *
2038
+ * :progress ::
2039
+ * A callback that will be executed for checkout progress notifications.
2040
+ * Up to 3 parameters are passed on each execution:
2041
+ *
2042
+ * - The path to the last updated file (or +nil+ on the very first invocation).
2043
+ * - The number of completed checkout steps.
2044
+ * - The number of total checkout steps to be performed.
2045
+ *
2046
+ * :notify ::
2047
+ * A callback that will be executed for each checkout notification types specified
2048
+ * with +:notify_flags+. Up to 5 parameters are passed on each execution:
2049
+ *
2050
+ * - An array containing the +:notify_flags+ that caused the callback execution.
2051
+ * - The path of the current file.
2052
+ * - A hash describing the baseline blob (or +nil+ if it does not exist).
2053
+ * - A hash describing the target blob (or +nil+ if it does not exist).
2054
+ * - A hash describing the workdir blob (or +nil+ if it does not exist).
2055
+ *
2056
+ * :strategy ::
2057
+ * A single symbol or an array of symbols representing the strategies to use when
2058
+ * performing the checkout. Possible values are:
2059
+ *
2060
+ * :none ::
2061
+ * Perform a dry run (default).
2062
+ *
2063
+ * :safe ::
2064
+ * Allow safe updates that cannot overwrite uncommitted data.
2065
+ *
2066
+ * :recreate_missing ::
2067
+ * Allow checkout to recreate missing files.
2068
+ *
2069
+ * :force ::
2070
+ * Allow all updates to force working directory to look like index.
2071
+ *
2072
+ * :allow_conflicts ::
2073
+ * Allow checkout to make safe updates even if conflicts are found.
2074
+ *
2075
+ * :remove_untracked ::
2076
+ * Remove untracked files not in index (that are not ignored).
2077
+ *
2078
+ * :remove_ignored ::
2079
+ * Remove ignored files not in index.
2080
+ *
2081
+ * :update_only ::
2082
+ * Only update existing files, don't create new ones.
2083
+ *
2084
+ * :dont_update_index ::
2085
+ * Normally checkout updates index entries as it goes; this stops that.
2086
+ *
2087
+ * :no_refresh ::
2088
+ * Don't refresh index/config/etc before doing checkout.
2089
+ *
2090
+ * :disable_pathspec_match ::
2091
+ * Treat pathspec as simple list of exact match file paths.
2092
+ *
2093
+ * :skip_locked_directories ::
2094
+ * Ignore directories in use, they will be left empty.
2095
+ *
2096
+ * :skip_unmerged ::
2097
+ * Allow checkout to skip unmerged files (NOT IMPLEMENTED).
2098
+ *
2099
+ * :use_ours ::
2100
+ * For unmerged files, checkout stage 2 from index (NOT IMPLEMENTED).
2101
+ *
2102
+ * :use_theirs ::
2103
+ * For unmerged files, checkout stage 3 from index (NOT IMPLEMENTED).
2104
+ *
2105
+ * :update_submodules ::
2106
+ * Recursively checkout submodules with same options (NOT IMPLEMENTED).
2107
+ *
2108
+ * :update_submodules_if_changed ::
2109
+ * Recursively checkout submodules if HEAD moved in super repo (NOT IMPLEMENTED).
2110
+ *
2111
+ * :disable_filters ::
2112
+ * If +true+, filters like CRLF line conversion will be disabled.
2113
+ *
2114
+ * :dir_mode ::
2115
+ * Mode for newly created directories. Default: +0755+.
2116
+ *
2117
+ * :file_mode ::
2118
+ * Mode for newly created files. Default: +0755+ or +0644+.
2119
+ *
2120
+ * :file_open_flags ::
2121
+ * Mode for opening files. Default: <code>IO::CREAT | IO::TRUNC | IO::WRONLY</code>.
2122
+ *
2123
+ * :notify_flags ::
2124
+ * A single symbol or an array of symbols representing the cases in which the +:notify+
2125
+ * callback should be invoked. Possible values are:
2126
+ *
2127
+ * :none ::
2128
+ * Do not invoke the +:notify+ callback (default).
2129
+ *
2130
+ * :conflict ::
2131
+ * Invoke the callback for conflicting paths.
2132
+ *
2133
+ * :dirty ::
2134
+ * Invoke the callback for "dirty" files, i.e. those that do not need an update but
2135
+ * no longer match the baseline.
2136
+ *
2137
+ * :updated ::
2138
+ * Invoke the callback for any file that was changed.
2139
+ *
2140
+ * :untracked ::
2141
+ * Invoke the callback for untracked files.
2142
+ *
2143
+ * :ignored ::
2144
+ * Invoke the callback for ignored files.
2145
+ *
2146
+ * :all ::
2147
+ * Invoke the callback for all these cases.
2148
+ *
2149
+ * :paths ::
2150
+ * A glob string or an array of glob strings specifying which paths should be taken
2151
+ * into account for the checkout operation. +nil+ will match all files.
2152
+ * Default: +nil+.
2153
+ *
2154
+ * :baseline ::
2155
+ * A Rugged::Tree that represents the current, expected contents of the workdir.
2156
+ * Default: +HEAD+.
2157
+ *
2158
+ * :target_directory ::
2159
+ * A path to an alternative workdir directory in which the checkout should be performed.
2160
+ */
2161
+ static VALUE rb_git_checkout_tree(int argc, VALUE *argv, VALUE self)
2162
+ {
2163
+ VALUE rb_treeish, rb_options;
2164
+ git_repository *repo;
2165
+ git_object *treeish;
2166
+ git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
2167
+ struct rugged_cb_payload *payload;
2168
+ int error, exception = 0;
2169
+
2170
+ rb_scan_args(argc, argv, "10:", &rb_treeish, &rb_options);
2171
+
2172
+ if (TYPE(rb_treeish) == T_STRING) {
2173
+ rb_treeish = rugged_object_rev_parse(self, rb_treeish, 1);
2174
+ }
2175
+
2176
+ if (!rb_obj_is_kind_of(rb_treeish, rb_cRuggedCommit) &&
2177
+ !rb_obj_is_kind_of(rb_treeish, rb_cRuggedTag) &&
2178
+ !rb_obj_is_kind_of(rb_treeish, rb_cRuggedTree)) {
2179
+ rb_raise(rb_eTypeError, "Expected Rugged::Commit, Rugged::Tag or Rugged::Tree");
2180
+ }
2181
+
2182
+ Data_Get_Struct(self, git_repository, repo);
2183
+ Data_Get_Struct(rb_treeish, git_object, treeish);
2184
+
2185
+ rugged_parse_checkout_options(&opts, rb_options);
2186
+
2187
+ error = git_checkout_tree(repo, treeish, &opts);
2188
+ xfree(opts.paths.strings);
2189
+
2190
+ if ((payload = opts.notify_payload) != NULL) {
2191
+ exception = payload->exception;
2192
+ xfree(opts.notify_payload);
2193
+ }
2194
+
2195
+ if ((payload = opts.progress_payload) != NULL) {
2196
+ exception = payload->exception;
2197
+ xfree(opts.progress_payload);
2198
+ }
2199
+
2200
+ if (exception)
2201
+ rb_jump_tag(exception);
2202
+
2203
+ rugged_exception_check(error);
2204
+
2205
+ return Qnil;
2206
+ }
2207
+
2208
+ /**
2209
+ * call-seq: repo.checkout_index(index[,options]) -> nil
2210
+ *
2211
+ * Updates files in the index and the working tree to match the content of the
2212
+ * commit pointed at by +index+.
2213
+ *
2214
+ * See Repository#checkout_tree for a list of supported +options+.
2215
+ */
2216
+ static VALUE rb_git_checkout_index(int argc, VALUE *argv, VALUE self)
2217
+ {
2218
+ VALUE rb_index, rb_options;
2219
+ git_repository *repo;
2220
+ git_index *index;
2221
+ git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
2222
+ struct rugged_cb_payload *payload;
2223
+ int error, exception = 0;
2224
+
2225
+ rb_scan_args(argc, argv, "10:", &rb_index, &rb_options);
2226
+
2227
+ if (!rb_obj_is_kind_of(rb_index, rb_cRuggedIndex))
2228
+ rb_raise(rb_eTypeError, "Expected Rugged::Index");
2229
+
2230
+ Data_Get_Struct(self, git_repository, repo);
2231
+ Data_Get_Struct(rb_index, git_index, index);
2232
+
2233
+ rugged_parse_checkout_options(&opts, rb_options);
2234
+
2235
+ error = git_checkout_index(repo, index, &opts);
2236
+ xfree(opts.paths.strings);
2237
+
2238
+ if ((payload = opts.notify_payload) != NULL) {
2239
+ exception = payload->exception;
2240
+ xfree(opts.notify_payload);
2241
+ }
2242
+
2243
+ if ((payload = opts.progress_payload) != NULL) {
2244
+ exception = payload->exception;
2245
+ xfree(opts.progress_payload);
2246
+ }
2247
+
2248
+ if (exception)
2249
+ rb_jump_tag(exception);
2250
+
2251
+ rugged_exception_check(error);
2252
+
2253
+ return Qnil;
2254
+ }
2255
+
2256
+ /**
2257
+ * call-seq: repo.checkout_head([options]) -> nil
2258
+ *
2259
+ * Updates files in the index and the working tree to match the content of the
2260
+ * commit pointed at by +HEAD+.
2261
+ *
2262
+ * See Repository#checkout_tree for a list of supported +options+.
2263
+ */
2264
+ static VALUE rb_git_checkout_head(int argc, VALUE *argv, VALUE self)
2265
+ {
2266
+ VALUE rb_options;
2267
+ git_repository *repo;
2268
+ git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
2269
+ struct rugged_cb_payload *payload;
2270
+ int error, exception = 0;
2271
+
2272
+ rb_scan_args(argc, argv, "00:", &rb_options);
2273
+
2274
+ Data_Get_Struct(self, git_repository, repo);
2275
+
2276
+ rugged_parse_checkout_options(&opts, rb_options);
2277
+
2278
+ error = git_checkout_head(repo, &opts);
2279
+ xfree(opts.paths.strings);
2280
+
2281
+ if ((payload = opts.notify_payload) != NULL) {
2282
+ exception = payload->exception;
2283
+ xfree(opts.notify_payload);
2284
+ }
2285
+
2286
+ if ((payload = opts.progress_payload) != NULL) {
2287
+ exception = payload->exception;
2288
+ xfree(opts.progress_payload);
2289
+ }
2290
+
2291
+ if (exception)
2292
+ rb_jump_tag(exception);
2293
+
2294
+ rugged_exception_check(error);
2295
+
2296
+ return Qnil;
2297
+ }
2298
+
2299
+ /*
2300
+ * call-seq:
2301
+ * repo.path_ignored?(path) -> true or false
2302
+ *
2303
+ * Return whether a path is ignored or not.
2304
+ */
2305
+ static VALUE rb_git_repo_is_path_ignored(VALUE self, VALUE rb_path) {
2306
+ git_repository *repo;
2307
+ const char *path;
2308
+ int error;
2309
+ int ignored;
2310
+
2311
+ Data_Get_Struct(self, git_repository, repo);
2312
+ path = StringValueCStr(rb_path);
2313
+ error = git_ignore_path_is_ignored(&ignored, repo, path);
2314
+ rugged_exception_check(error);
2315
+ return ignored ? Qtrue : Qfalse;
2316
+ }
2317
+
2318
+ static void rugged_parse_cherrypick_options(git_cherrypick_options *opts, VALUE rb_options)
2319
+ {
2320
+ VALUE rb_value;
2321
+
2322
+ if (NIL_P(rb_options))
2323
+ return;
2324
+
2325
+ Check_Type(rb_options, T_HASH);
2326
+
2327
+ rb_value = rb_hash_aref(rb_options, CSTR2SYM("mainline"));
2328
+ if (!NIL_P(rb_value)) {
2329
+ opts->mainline = FIX2UINT(rb_value);
2330
+ }
2331
+ }
2332
+
2333
+ static VALUE rugged_create_attr(const char *attr)
2334
+ {
2335
+ switch (git_attr_value(attr)) {
2336
+ case GIT_ATTR_TRUE_T:
2337
+ return Qtrue;
2338
+
2339
+ case GIT_ATTR_FALSE_T:
2340
+ return Qfalse;
2341
+
2342
+ case GIT_ATTR_VALUE_T:
2343
+ return rb_str_new2(attr);
2344
+
2345
+ case GIT_ATTR_UNSPECIFIED_T:
2346
+ default:
2347
+ return Qnil;
2348
+ }
2349
+ }
2350
+
2351
+ static int foreach_attr_hash(const char *name, const char *value, void *payload)
2352
+ {
2353
+ VALUE rb_hash = (VALUE)payload;
2354
+ rb_hash_aset(rb_hash, rb_str_new2(name), rugged_create_attr(value));
2355
+ return 0;
2356
+ }
2357
+
2358
+ static VALUE rb_git_repo_attributes(int argc, VALUE *argv, VALUE self)
2359
+ {
2360
+ VALUE rb_path, rb_names, rb_options;
2361
+
2362
+ git_repository *repo;
2363
+ int error, options = 0;
2364
+
2365
+ rb_scan_args(argc, argv, "12", &rb_path, &rb_names, &rb_options);
2366
+
2367
+ Data_Get_Struct(self, git_repository, repo);
2368
+ FilePathValue(rb_path);
2369
+
2370
+ if (!NIL_P(rb_options)) {
2371
+ Check_Type(rb_options, T_FIXNUM);
2372
+ options = FIX2INT(rb_options);
2373
+ }
2374
+
2375
+ switch (TYPE(rb_names)) {
2376
+ case T_ARRAY:
2377
+ {
2378
+ VALUE rb_result;
2379
+ const char **values;
2380
+ const char **names;
2381
+ long i, num_attr = RARRAY_LEN(rb_names);
2382
+
2383
+ if (num_attr > 32)
2384
+ rb_raise(rb_eRuntimeError, "Too many attributes requested");
2385
+
2386
+ values = alloca(num_attr * sizeof(const char *));
2387
+ names = alloca(num_attr * sizeof(const char *));
2388
+
2389
+ for (i = 0; i < num_attr; ++i) {
2390
+ VALUE attr = rb_ary_entry(rb_names, i);
2391
+ Check_Type(attr, T_STRING);
2392
+ names[i] = StringValueCStr(attr);
2393
+ }
2394
+
2395
+ error = git_attr_get_many(
2396
+ values, repo, options,
2397
+ StringValueCStr(rb_path),
2398
+ (size_t)num_attr, names);
2399
+
2400
+ rugged_exception_check(error);
2401
+
2402
+ rb_result = rb_hash_new();
2403
+ for (i = 0; i < num_attr; ++i) {
2404
+ VALUE attr = rb_ary_entry(rb_names, i);
2405
+ rb_hash_aset(rb_result, attr, rugged_create_attr(values[i]));
2406
+ }
2407
+ return rb_result;
2408
+ }
2409
+
2410
+ case T_STRING:
2411
+ {
2412
+ const char *value;
2413
+
2414
+ error = git_attr_get(
2415
+ &value, repo, options,
2416
+ StringValueCStr(rb_path),
2417
+ StringValueCStr(rb_names));
2418
+
2419
+ rugged_exception_check(error);
2420
+
2421
+ return rugged_create_attr(value);
2422
+ }
2423
+
2424
+ case T_NIL:
2425
+ {
2426
+ VALUE rb_result = rb_hash_new();
2427
+
2428
+ error = git_attr_foreach(
2429
+ repo, options,
2430
+ StringValueCStr(rb_path),
2431
+ &foreach_attr_hash,
2432
+ (void *)rb_result);
2433
+
2434
+ rugged_exception_check(error);
2435
+ return rb_result;
2436
+ }
2437
+
2438
+ default:
2439
+ rb_raise(rb_eTypeError,
2440
+ "Invalid attribute name (expected String or Array)");
2441
+ }
2442
+ }
2443
+
2444
+ /*
2445
+ * call-seq:
2446
+ * repo.cherrypick(commit[, options]) -> nil
2447
+ *
2448
+ * Cherry-pick the given commit and update the index and working
2449
+ * directory accordingly.
2450
+ *
2451
+ * `commit` can be either a string containing a commit id or a
2452
+ * `Rugged::Commit` object.
2453
+ *
2454
+ * The following options can be passed in the +options+ Hash:
2455
+ *
2456
+ * :mainline ::
2457
+ * When cherry-picking a merge, you need to specify the parent number
2458
+ * (starting from 1) which should be considered the mainline.
2459
+ */
2460
+ static VALUE rb_git_repo_cherrypick(int argc, VALUE *argv, VALUE self)
2461
+ {
2462
+ VALUE rb_options, rb_commit;
2463
+
2464
+ git_repository *repo;
2465
+ git_commit *commit;
2466
+ git_cherrypick_options opts = GIT_CHERRYPICK_OPTIONS_INIT;
2467
+
2468
+ int error;
2469
+
2470
+ rb_scan_args(argc, argv, "10:", &rb_commit, &rb_options);
2471
+
2472
+ if (TYPE(rb_commit) == T_STRING) {
2473
+ rb_commit = rugged_object_rev_parse(self, rb_commit, 1);
2474
+ }
2475
+
2476
+ if (!rb_obj_is_kind_of(rb_commit, rb_cRuggedCommit)) {
2477
+ rb_raise(rb_eArgError, "Expected a Rugged::Commit.");
2478
+ }
2479
+
2480
+ Data_Get_Struct(self, git_repository, repo);
2481
+ Data_Get_Struct(rb_commit, git_commit, commit);
2482
+
2483
+ rugged_parse_cherrypick_options(&opts, rb_options);
2484
+
2485
+ error = git_cherrypick(repo, commit, &opts);
2486
+ rugged_exception_check(error);
2487
+
2488
+ return Qnil;
2489
+ }
2490
+
2491
+ /*
2492
+ * call-seq:
2493
+ * repo.cherrypick_commit(commit, our_commit, [mainline, options]) -> nil
2494
+ *
2495
+ * Cherry-pick the given commit on the given base in-memory and
2496
+ * return an index with the result.
2497
+ *
2498
+ * `commit` can be either a string containing a commit id or a
2499
+ * `Rugged::Commit` object.
2500
+ *
2501
+ * `our_commit` is the base commit, can be either a string containing
2502
+ * a commit id or a `Rugged::Commit` object.
2503
+ *
2504
+ * `mainline` when cherry-picking a merge, this is the parent number
2505
+ * (starting from 1) which should be considered the mainline.
2506
+ */
2507
+ static VALUE rb_git_repo_cherrypick_commit(int argc, VALUE *argv, VALUE self)
2508
+ {
2509
+ VALUE rb_options, rb_commit, rb_our_commit, rb_mainline;
2510
+
2511
+ git_repository *repo;
2512
+ git_commit *commit, *our_commit;
2513
+ git_merge_options opts = GIT_MERGE_OPTIONS_INIT;
2514
+ git_index *index;
2515
+ int error, mainline;
2516
+
2517
+ rb_scan_args(argc, argv, "21:", &rb_commit, &rb_our_commit, &rb_mainline, &rb_options);
2518
+
2519
+ if (TYPE(rb_commit) == T_STRING) {
2520
+ rb_commit = rugged_object_rev_parse(self, rb_commit, 1);
2521
+ }
2522
+ if (TYPE(rb_our_commit) == T_STRING) {
2523
+ rb_our_commit = rugged_object_rev_parse(self, rb_our_commit, 1);
2524
+ }
2525
+
2526
+ if (!rb_obj_is_kind_of(rb_commit, rb_cRuggedCommit)) {
2527
+ rb_raise(rb_eArgError, "Expected a Rugged::Commit.");
2528
+ }
2529
+ if (!rb_obj_is_kind_of(rb_our_commit, rb_cRuggedCommit)) {
2530
+ rb_raise(rb_eArgError, "Expected a Rugged::Commit.");
2531
+ }
2532
+
2533
+ Data_Get_Struct(self, git_repository, repo);
2534
+ Data_Get_Struct(rb_commit, git_commit, commit);
2535
+ Data_Get_Struct(rb_our_commit, git_commit, our_commit);
2536
+
2537
+ rugged_parse_merge_options(&opts, rb_options);
2538
+
2539
+ mainline = NIL_P(rb_mainline) ? 0 : FIX2UINT(rb_mainline);
2540
+ error = git_cherrypick_commit(&index, repo, commit, our_commit, mainline, &opts);
2541
+ rugged_exception_check(error);
2542
+
2543
+ return rugged_index_new(rb_cRuggedIndex, self, index);
2544
+ }
2545
+
1387
2546
  void Init_rugged_repo(void)
1388
2547
  {
1389
2548
  id_call = rb_intern("call");
@@ -1392,8 +2551,8 @@ void Init_rugged_repo(void)
1392
2551
 
1393
2552
  rb_define_singleton_method(rb_cRuggedRepo, "new", rb_git_repo_new, -1);
1394
2553
  rb_define_singleton_method(rb_cRuggedRepo, "bare", rb_git_repo_open_bare, -1);
1395
- rb_define_singleton_method(rb_cRuggedRepo, "hash", rb_git_repo_hash, 2);
1396
- rb_define_singleton_method(rb_cRuggedRepo, "hash_file", rb_git_repo_hashfile, 2);
2554
+ rb_define_singleton_method(rb_cRuggedRepo, "hash_data", rb_git_repo_hash, 2);
2555
+ rb_define_singleton_method(rb_cRuggedRepo, "hash_file", rb_git_repo_hashfile, 2);
1397
2556
  rb_define_singleton_method(rb_cRuggedRepo, "init_at", rb_git_repo_init_at, -1);
1398
2557
  rb_define_singleton_method(rb_cRuggedRepo, "discover", rb_git_repo_discover, -1);
1399
2558
  rb_define_singleton_method(rb_cRuggedRepo, "clone_at", rb_git_repo_clone_at, -1);
@@ -1402,6 +2561,8 @@ void Init_rugged_repo(void)
1402
2561
 
1403
2562
  rb_define_method(rb_cRuggedRepo, "exists?", rb_git_repo_exists, 1);
1404
2563
  rb_define_method(rb_cRuggedRepo, "include?", rb_git_repo_exists, 1);
2564
+ rb_define_method(rb_cRuggedRepo, "expand_oids", rb_git_repo_expand_oids, -1);
2565
+ rb_define_method(rb_cRuggedRepo, "descendant_of?", rb_git_repo_descendant_of, 2);
1405
2566
 
1406
2567
  rb_define_method(rb_cRuggedRepo, "read", rb_git_repo_read, 1);
1407
2568
  rb_define_method(rb_cRuggedRepo, "read_header", rb_git_repo_read_header, 1);
@@ -1411,24 +2572,36 @@ void Init_rugged_repo(void)
1411
2572
  rb_define_method(rb_cRuggedRepo, "path", rb_git_repo_path, 0);
1412
2573
  rb_define_method(rb_cRuggedRepo, "workdir", rb_git_repo_workdir, 0);
1413
2574
  rb_define_method(rb_cRuggedRepo, "workdir=", rb_git_repo_set_workdir, 1);
1414
- rb_define_method(rb_cRuggedRepo, "status", rb_git_repo_status, -1);
1415
-
1416
- rb_define_method(rb_cRuggedRepo, "push", rb_git_repo_push, 2);
2575
+ rb_define_private_method(rb_cRuggedRepo, "file_status", rb_git_repo_file_status, 1);
2576
+ rb_define_private_method(rb_cRuggedRepo, "each_status", rb_git_repo_file_each_status, 0);
1417
2577
 
1418
2578
  rb_define_method(rb_cRuggedRepo, "index", rb_git_repo_get_index, 0);
1419
2579
  rb_define_method(rb_cRuggedRepo, "index=", rb_git_repo_set_index, 1);
1420
2580
  rb_define_method(rb_cRuggedRepo, "config", rb_git_repo_get_config, 0);
1421
2581
  rb_define_method(rb_cRuggedRepo, "config=", rb_git_repo_set_config, 1);
1422
2582
 
2583
+ rb_define_method(rb_cRuggedRepo, "ident", rb_git_repo_get_ident, 0);
2584
+ rb_define_method(rb_cRuggedRepo, "ident=", rb_git_repo_set_ident, 1);
2585
+
1423
2586
  rb_define_method(rb_cRuggedRepo, "bare?", rb_git_repo_is_bare, 0);
2587
+ rb_define_method(rb_cRuggedRepo, "shallow?", rb_git_repo_is_shallow, 0);
1424
2588
  rb_define_method(rb_cRuggedRepo, "empty?", rb_git_repo_is_empty, 0);
1425
2589
 
1426
2590
  rb_define_method(rb_cRuggedRepo, "head_detached?", rb_git_repo_head_detached, 0);
1427
- rb_define_method(rb_cRuggedRepo, "head_orphan?", rb_git_repo_head_orphan, 0);
2591
+ rb_define_method(rb_cRuggedRepo, "head_unborn?", rb_git_repo_head_unborn, 0);
1428
2592
  rb_define_method(rb_cRuggedRepo, "head=", rb_git_repo_set_head, 1);
1429
2593
  rb_define_method(rb_cRuggedRepo, "head", rb_git_repo_get_head, 0);
1430
2594
 
1431
2595
  rb_define_method(rb_cRuggedRepo, "merge_base", rb_git_repo_merge_base, -2);
2596
+ rb_define_method(rb_cRuggedRepo, "merge_bases", rb_git_repo_merge_bases, -2);
2597
+
2598
+ rb_define_method(rb_cRuggedRepo, "merge_analysis", rb_git_repo_merge_analysis, -1);
2599
+ rb_define_method(rb_cRuggedRepo, "merge_commits", rb_git_repo_merge_commits, -1);
2600
+
2601
+ rb_define_method(rb_cRuggedRepo, "revert_commit", rb_git_repo_revert_commit, -1);
2602
+
2603
+ rb_define_method(rb_cRuggedRepo, "path_ignored?", rb_git_repo_is_path_ignored, 1);
2604
+
1432
2605
  rb_define_method(rb_cRuggedRepo, "reset", rb_git_repo_reset, 2);
1433
2606
  rb_define_method(rb_cRuggedRepo, "reset_path", rb_git_repo_reset_path, -1);
1434
2607
 
@@ -1437,6 +2610,16 @@ void Init_rugged_repo(void)
1437
2610
 
1438
2611
  rb_define_method(rb_cRuggedRepo, "ahead_behind", rb_git_repo_ahead_behind, 2);
1439
2612
 
2613
+ rb_define_method(rb_cRuggedRepo, "default_signature", rb_git_repo_default_signature, 0);
2614
+
2615
+ rb_define_method(rb_cRuggedRepo, "checkout_tree", rb_git_checkout_tree, -1);
2616
+ rb_define_method(rb_cRuggedRepo, "checkout_index", rb_git_checkout_index, -1);
2617
+ rb_define_method(rb_cRuggedRepo, "checkout_head", rb_git_checkout_head, -1);
2618
+
2619
+ rb_define_method(rb_cRuggedRepo, "cherrypick", rb_git_repo_cherrypick, -1);
2620
+ rb_define_method(rb_cRuggedRepo, "cherrypick_commit", rb_git_repo_cherrypick_commit, -1);
2621
+ rb_define_method(rb_cRuggedRepo, "fetch_attributes", rb_git_repo_attributes, -1);
2622
+
1440
2623
  rb_cRuggedOdbObject = rb_define_class_under(rb_mRugged, "OdbObject", rb_cObject);
1441
2624
  rb_define_method(rb_cRuggedOdbObject, "data", rb_git_odbobj_data, 0);
1442
2625
  rb_define_method(rb_cRuggedOdbObject, "len", rb_git_odbobj_size, 0);