rugged 0.16.0 → 0.17.0b1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (392) hide show
  1. data/README.md +373 -243
  2. data/Rakefile +22 -0
  3. data/ext/rugged/extconf.rb +9 -6
  4. data/ext/rugged/rugged.c +123 -31
  5. data/ext/rugged/rugged.h +11 -10
  6. data/ext/rugged/rugged_blob.c +181 -18
  7. data/ext/rugged/rugged_commit.c +196 -18
  8. data/ext/rugged/rugged_config.c +94 -5
  9. data/ext/rugged/rugged_object.c +54 -1
  10. data/ext/rugged/rugged_reference.c +203 -15
  11. data/ext/rugged/{remote.c → rugged_remote.c} +35 -10
  12. data/ext/rugged/rugged_repo.c +323 -81
  13. data/ext/rugged/rugged_revwalk.c +57 -4
  14. data/ext/rugged/rugged_signature.c +3 -3
  15. data/ext/rugged/rugged_tag.c +72 -1
  16. data/ext/rugged/rugged_tree.c +70 -2
  17. data/ext/rugged/vendor/libgit2-dist/deps/regex/config.h +7 -0
  18. data/ext/rugged/vendor/libgit2-dist/deps/regex/regcomp.c +3856 -0
  19. data/ext/rugged/vendor/libgit2-dist/deps/regex/regex.c +85 -0
  20. data/ext/rugged/vendor/libgit2-dist/deps/regex/regex.h +582 -0
  21. data/ext/rugged/vendor/libgit2-dist/deps/regex/regex_internal.c +1744 -0
  22. data/ext/rugged/vendor/libgit2-dist/deps/regex/regex_internal.h +810 -0
  23. data/ext/rugged/vendor/libgit2-dist/deps/regex/regexec.c +4369 -0
  24. data/ext/rugged/vendor/libgit2-dist/examples/diff.c +238 -0
  25. data/ext/rugged/vendor/libgit2-dist/examples/general.c +4 -4
  26. data/ext/rugged/vendor/libgit2-dist/examples/network/fetch.c +101 -85
  27. data/ext/rugged/vendor/libgit2-dist/examples/network/git2.c +7 -3
  28. data/ext/rugged/vendor/libgit2-dist/examples/network/index-pack.c +80 -25
  29. data/ext/rugged/vendor/libgit2-dist/examples/network/ls-remote.c +6 -6
  30. data/ext/rugged/vendor/libgit2-dist/include/git2/attr.h +224 -0
  31. data/ext/rugged/vendor/libgit2-dist/include/git2/blob.h +59 -5
  32. data/ext/rugged/vendor/libgit2-dist/include/git2/branch.h +114 -7
  33. data/ext/rugged/vendor/libgit2-dist/include/git2/commit.h +14 -7
  34. data/ext/rugged/vendor/libgit2-dist/include/git2/common.h +4 -3
  35. data/ext/rugged/vendor/libgit2-dist/include/git2/config.h +105 -27
  36. data/ext/rugged/vendor/libgit2-dist/include/git2/diff.h +409 -0
  37. data/ext/rugged/vendor/libgit2-dist/include/git2/errors.h +47 -82
  38. data/ext/rugged/vendor/libgit2-dist/include/git2/index.h +25 -10
  39. data/ext/rugged/vendor/libgit2-dist/include/git2/indexer.h +46 -1
  40. data/ext/rugged/vendor/libgit2-dist/include/git2/merge.h +35 -0
  41. data/ext/rugged/vendor/libgit2-dist/include/git2/net.h +1 -1
  42. data/ext/rugged/vendor/libgit2-dist/include/git2/notes.h +139 -0
  43. data/ext/rugged/vendor/libgit2-dist/include/git2/object.h +5 -5
  44. data/ext/rugged/vendor/libgit2-dist/include/git2/odb.h +13 -13
  45. data/ext/rugged/vendor/libgit2-dist/include/git2/odb_backend.h +8 -8
  46. data/ext/rugged/vendor/libgit2-dist/include/git2/oid.h +14 -9
  47. data/ext/rugged/vendor/libgit2-dist/include/git2/reflog.h +5 -5
  48. data/ext/rugged/vendor/libgit2-dist/include/git2/refs.h +37 -17
  49. data/ext/rugged/vendor/libgit2-dist/include/git2/refspec.h +17 -9
  50. data/ext/rugged/vendor/libgit2-dist/include/git2/remote.h +83 -16
  51. data/ext/rugged/vendor/libgit2-dist/include/git2/repository.h +24 -10
  52. data/ext/rugged/vendor/libgit2-dist/include/git2/reset.h +44 -0
  53. data/ext/rugged/vendor/libgit2-dist/include/git2/revparse.h +36 -0
  54. data/ext/rugged/vendor/libgit2-dist/include/git2/revwalk.h +74 -6
  55. data/ext/rugged/vendor/libgit2-dist/include/git2/signature.h +3 -3
  56. data/ext/rugged/vendor/libgit2-dist/include/git2/status.h +120 -19
  57. data/ext/rugged/vendor/libgit2-dist/include/git2/submodule.h +103 -0
  58. data/ext/rugged/vendor/libgit2-dist/include/git2/tag.h +28 -10
  59. data/ext/rugged/vendor/libgit2-dist/include/git2/threads.h +1 -1
  60. data/ext/rugged/vendor/libgit2-dist/include/git2/tree.h +13 -13
  61. data/ext/rugged/vendor/libgit2-dist/include/git2/types.h +16 -2
  62. data/ext/rugged/vendor/libgit2-dist/include/git2/version.h +3 -3
  63. data/ext/rugged/vendor/libgit2-dist/include/git2/windows.h +1 -1
  64. data/ext/rugged/vendor/libgit2-dist/include/git2.h +7 -2
  65. data/ext/rugged/vendor/libgit2-dist/src/attr.c +677 -0
  66. data/ext/rugged/vendor/libgit2-dist/src/attr.h +56 -0
  67. data/ext/rugged/vendor/libgit2-dist/src/attr_file.c +609 -0
  68. data/ext/rugged/vendor/libgit2-dist/src/attr_file.h +145 -0
  69. data/ext/rugged/vendor/libgit2-dist/src/blob.c +213 -60
  70. data/ext/rugged/vendor/libgit2-dist/src/blob.h +2 -1
  71. data/ext/rugged/vendor/libgit2-dist/src/branch.c +208 -0
  72. data/ext/rugged/vendor/libgit2-dist/src/branch.h +17 -0
  73. data/ext/rugged/vendor/libgit2-dist/src/bswap.h +1 -1
  74. data/ext/rugged/vendor/libgit2-dist/src/buffer.c +395 -46
  75. data/ext/rugged/vendor/libgit2-dist/src/buffer.h +112 -9
  76. data/ext/rugged/vendor/libgit2-dist/src/cache.c +37 -49
  77. data/ext/rugged/vendor/libgit2-dist/src/cache.h +7 -17
  78. data/ext/rugged/vendor/libgit2-dist/src/cc-compat.h +18 -16
  79. data/ext/rugged/vendor/libgit2-dist/src/commit.c +56 -90
  80. data/ext/rugged/vendor/libgit2-dist/src/commit.h +1 -1
  81. data/ext/rugged/vendor/libgit2-dist/src/common.h +12 -5
  82. data/ext/rugged/vendor/libgit2-dist/src/{win32 → compat}/fnmatch.c +1 -1
  83. data/ext/rugged/vendor/libgit2-dist/src/{win32 → compat}/fnmatch.h +3 -3
  84. data/ext/rugged/vendor/libgit2-dist/src/config.c +247 -158
  85. data/ext/rugged/vendor/libgit2-dist/src/config.h +10 -1
  86. data/ext/rugged/vendor/libgit2-dist/src/config_cache.c +94 -0
  87. data/ext/rugged/vendor/libgit2-dist/src/config_file.c +606 -496
  88. data/ext/rugged/vendor/libgit2-dist/src/config_file.h +31 -0
  89. data/ext/rugged/vendor/libgit2-dist/src/crlf.c +228 -0
  90. data/ext/rugged/vendor/libgit2-dist/src/date.c +876 -0
  91. data/ext/rugged/vendor/libgit2-dist/src/delta-apply.c +15 -9
  92. data/ext/rugged/vendor/libgit2-dist/src/delta-apply.h +2 -2
  93. data/ext/rugged/vendor/libgit2-dist/src/diff.c +814 -0
  94. data/ext/rugged/vendor/libgit2-dist/src/diff.h +43 -0
  95. data/ext/rugged/vendor/libgit2-dist/src/diff_output.c +794 -0
  96. data/ext/rugged/vendor/libgit2-dist/src/errors.c +89 -74
  97. data/ext/rugged/vendor/libgit2-dist/src/fetch.c +94 -66
  98. data/ext/rugged/vendor/libgit2-dist/src/fetch.h +5 -4
  99. data/ext/rugged/vendor/libgit2-dist/src/filebuf.c +157 -100
  100. data/ext/rugged/vendor/libgit2-dist/src/filebuf.h +22 -8
  101. data/ext/rugged/vendor/libgit2-dist/src/fileops.c +330 -206
  102. data/ext/rugged/vendor/libgit2-dist/src/fileops.h +82 -51
  103. data/ext/rugged/vendor/libgit2-dist/src/filter.c +165 -0
  104. data/ext/rugged/vendor/libgit2-dist/src/filter.h +119 -0
  105. data/ext/rugged/vendor/libgit2-dist/src/global.c +4 -4
  106. data/ext/rugged/vendor/libgit2-dist/src/global.h +4 -1
  107. data/ext/rugged/vendor/libgit2-dist/src/hash.c +1 -1
  108. data/ext/rugged/vendor/libgit2-dist/src/hash.h +1 -1
  109. data/ext/rugged/vendor/libgit2-dist/src/ignore.c +203 -0
  110. data/ext/rugged/vendor/libgit2-dist/src/ignore.h +38 -0
  111. data/ext/rugged/vendor/libgit2-dist/src/index.c +220 -169
  112. data/ext/rugged/vendor/libgit2-dist/src/index.h +5 -1
  113. data/ext/rugged/vendor/libgit2-dist/src/indexer.c +601 -102
  114. data/ext/rugged/vendor/libgit2-dist/src/iterator.c +748 -0
  115. data/ext/rugged/vendor/libgit2-dist/src/iterator.h +151 -0
  116. data/ext/rugged/vendor/libgit2-dist/src/khash.h +608 -0
  117. data/ext/rugged/vendor/libgit2-dist/src/map.h +6 -1
  118. data/ext/rugged/vendor/libgit2-dist/src/message.c +61 -0
  119. data/ext/rugged/vendor/libgit2-dist/src/message.h +14 -0
  120. data/ext/rugged/vendor/libgit2-dist/src/mwindow.c +27 -29
  121. data/ext/rugged/vendor/libgit2-dist/src/mwindow.h +4 -4
  122. data/ext/rugged/vendor/libgit2-dist/src/netops.c +375 -56
  123. data/ext/rugged/vendor/libgit2-dist/src/netops.h +12 -9
  124. data/ext/rugged/vendor/libgit2-dist/src/notes.c +548 -0
  125. data/ext/rugged/vendor/libgit2-dist/src/notes.h +28 -0
  126. data/ext/rugged/vendor/libgit2-dist/src/object.c +59 -21
  127. data/ext/rugged/vendor/libgit2-dist/src/odb.c +212 -175
  128. data/ext/rugged/vendor/libgit2-dist/src/odb.h +39 -2
  129. data/ext/rugged/vendor/libgit2-dist/src/odb_loose.c +238 -241
  130. data/ext/rugged/vendor/libgit2-dist/src/odb_pack.c +94 -106
  131. data/ext/rugged/vendor/libgit2-dist/src/oid.c +59 -60
  132. data/ext/rugged/vendor/libgit2-dist/src/oidmap.h +42 -0
  133. data/ext/rugged/vendor/libgit2-dist/src/pack.c +198 -170
  134. data/ext/rugged/vendor/libgit2-dist/src/pack.h +16 -9
  135. data/ext/rugged/vendor/libgit2-dist/src/path.c +496 -106
  136. data/ext/rugged/vendor/libgit2-dist/src/path.h +214 -20
  137. data/ext/rugged/vendor/libgit2-dist/src/pkt.c +88 -159
  138. data/ext/rugged/vendor/libgit2-dist/src/pkt.h +9 -5
  139. data/ext/rugged/vendor/libgit2-dist/src/pool.c +294 -0
  140. data/ext/rugged/vendor/libgit2-dist/src/pool.h +125 -0
  141. data/ext/rugged/vendor/libgit2-dist/src/posix.c +38 -16
  142. data/ext/rugged/vendor/libgit2-dist/src/posix.h +20 -2
  143. data/ext/rugged/vendor/libgit2-dist/src/ppc/sha1.c +1 -1
  144. data/ext/rugged/vendor/libgit2-dist/src/ppc/sha1.h +1 -1
  145. data/ext/rugged/vendor/libgit2-dist/src/pqueue.c +7 -7
  146. data/ext/rugged/vendor/libgit2-dist/src/pqueue.h +1 -1
  147. data/ext/rugged/vendor/libgit2-dist/src/protocol.c +21 -13
  148. data/ext/rugged/vendor/libgit2-dist/src/protocol.h +1 -1
  149. data/ext/rugged/vendor/libgit2-dist/src/reflog.c +125 -103
  150. data/ext/rugged/vendor/libgit2-dist/src/reflog.h +1 -1
  151. data/ext/rugged/vendor/libgit2-dist/src/refs.c +713 -640
  152. data/ext/rugged/vendor/libgit2-dist/src/refs.h +27 -3
  153. data/ext/rugged/vendor/libgit2-dist/src/refspec.c +51 -17
  154. data/ext/rugged/vendor/libgit2-dist/src/refspec.h +13 -1
  155. data/ext/rugged/vendor/libgit2-dist/src/remote.c +307 -119
  156. data/ext/rugged/vendor/libgit2-dist/src/remote.h +3 -2
  157. data/ext/rugged/vendor/libgit2-dist/src/repository.c +593 -442
  158. data/ext/rugged/vendor/libgit2-dist/src/repository.h +80 -2
  159. data/ext/rugged/vendor/libgit2-dist/src/reset.c +103 -0
  160. data/ext/rugged/vendor/libgit2-dist/src/revparse.c +753 -0
  161. data/ext/rugged/vendor/libgit2-dist/src/revwalk.c +434 -158
  162. data/ext/rugged/vendor/libgit2-dist/src/sha1.c +3 -3
  163. data/ext/rugged/vendor/libgit2-dist/src/sha1.h +2 -2
  164. data/ext/rugged/vendor/libgit2-dist/src/sha1_lookup.c +3 -2
  165. data/ext/rugged/vendor/libgit2-dist/src/sha1_lookup.h +1 -1
  166. data/ext/rugged/vendor/libgit2-dist/src/signature.c +69 -80
  167. data/ext/rugged/vendor/libgit2-dist/src/signature.h +1 -1
  168. data/ext/rugged/vendor/libgit2-dist/src/status.c +184 -638
  169. data/ext/rugged/vendor/libgit2-dist/src/strmap.h +64 -0
  170. data/ext/rugged/vendor/libgit2-dist/src/submodule.c +387 -0
  171. data/ext/rugged/vendor/libgit2-dist/src/tag.c +162 -137
  172. data/ext/rugged/vendor/libgit2-dist/src/tag.h +2 -1
  173. data/ext/rugged/vendor/libgit2-dist/src/thread-utils.c +1 -1
  174. data/ext/rugged/vendor/libgit2-dist/src/thread-utils.h +8 -8
  175. data/ext/rugged/vendor/libgit2-dist/src/transport.c +31 -19
  176. data/ext/rugged/vendor/libgit2-dist/src/transport.h +31 -11
  177. data/ext/rugged/vendor/libgit2-dist/src/transports/git.c +168 -193
  178. data/ext/rugged/vendor/libgit2-dist/src/transports/http.c +192 -241
  179. data/ext/rugged/vendor/libgit2-dist/src/transports/local.c +92 -86
  180. data/ext/rugged/vendor/libgit2-dist/src/tree-cache.c +32 -49
  181. data/ext/rugged/vendor/libgit2-dist/src/tree-cache.h +1 -1
  182. data/ext/rugged/vendor/libgit2-dist/src/tree.c +172 -145
  183. data/ext/rugged/vendor/libgit2-dist/src/tree.h +16 -2
  184. data/ext/rugged/vendor/libgit2-dist/src/tsort.c +16 -14
  185. data/ext/rugged/vendor/libgit2-dist/src/unix/map.c +8 -24
  186. data/ext/rugged/vendor/libgit2-dist/src/unix/posix.h +9 -3
  187. data/ext/rugged/vendor/libgit2-dist/src/util.c +94 -38
  188. data/ext/rugged/vendor/libgit2-dist/src/util.h +119 -13
  189. data/ext/rugged/vendor/libgit2-dist/src/vector.c +84 -31
  190. data/ext/rugged/vendor/libgit2-dist/src/vector.h +37 -4
  191. data/ext/rugged/vendor/libgit2-dist/src/win32/dir.c +81 -41
  192. data/ext/rugged/vendor/libgit2-dist/src/{dir.h → win32/dir.h} +4 -9
  193. data/ext/rugged/vendor/libgit2-dist/src/win32/map.c +19 -35
  194. data/ext/rugged/vendor/libgit2-dist/src/win32/mingw-compat.h +1 -1
  195. data/ext/rugged/vendor/libgit2-dist/src/win32/msvc-compat.h +5 -1
  196. data/ext/rugged/vendor/libgit2-dist/src/win32/posix.h +10 -8
  197. data/ext/rugged/vendor/libgit2-dist/src/win32/posix_w32.c +262 -118
  198. data/ext/rugged/vendor/libgit2-dist/src/win32/pthread.c +12 -9
  199. data/ext/rugged/vendor/libgit2-dist/src/win32/pthread.h +1 -1
  200. data/ext/rugged/vendor/libgit2-dist/src/win32/utf-conv.c +30 -26
  201. data/ext/rugged/vendor/libgit2-dist/src/win32/utf-conv.h +2 -1
  202. data/ext/rugged/vendor/libgit2-dist/src/xdiff/xdiff.h +135 -0
  203. data/ext/rugged/vendor/libgit2-dist/src/xdiff/xdiffi.c +572 -0
  204. data/ext/rugged/vendor/libgit2-dist/src/xdiff/xdiffi.h +63 -0
  205. data/ext/rugged/vendor/libgit2-dist/src/xdiff/xemit.c +253 -0
  206. data/ext/rugged/vendor/libgit2-dist/src/xdiff/xemit.h +36 -0
  207. data/ext/rugged/vendor/libgit2-dist/src/xdiff/xhistogram.c +371 -0
  208. data/ext/rugged/vendor/libgit2-dist/src/xdiff/xinclude.h +46 -0
  209. data/ext/rugged/vendor/libgit2-dist/src/xdiff/xmacros.h +54 -0
  210. data/ext/rugged/vendor/libgit2-dist/src/xdiff/xmerge.c +619 -0
  211. data/ext/rugged/vendor/libgit2-dist/src/xdiff/xpatience.c +358 -0
  212. data/ext/rugged/vendor/libgit2-dist/src/xdiff/xprepare.c +483 -0
  213. data/ext/rugged/vendor/libgit2-dist/src/xdiff/xprepare.h +34 -0
  214. data/ext/rugged/vendor/libgit2-dist/src/xdiff/xtypes.h +67 -0
  215. data/ext/rugged/vendor/libgit2-dist/src/xdiff/xutils.c +419 -0
  216. data/ext/rugged/vendor/libgit2-dist/src/xdiff/xutils.h +49 -0
  217. data/ext/rugged/vendor/libgit2-dist/tests-clar/attr/attr_expect.h +43 -0
  218. data/ext/rugged/vendor/libgit2-dist/tests-clar/attr/file.c +226 -0
  219. data/ext/rugged/vendor/libgit2-dist/tests-clar/attr/flags.c +108 -0
  220. data/ext/rugged/vendor/libgit2-dist/tests-clar/attr/lookup.c +262 -0
  221. data/ext/rugged/vendor/libgit2-dist/tests-clar/attr/repo.c +273 -0
  222. data/ext/rugged/vendor/libgit2-dist/{tests-clay → tests-clar}/buf/basic.c +5 -5
  223. data/ext/rugged/vendor/libgit2-dist/tests-clar/clar_helpers.c +181 -0
  224. data/ext/rugged/vendor/libgit2-dist/tests-clar/clar_libgit2.h +55 -0
  225. data/ext/rugged/vendor/libgit2-dist/tests-clar/commit/commit.c +44 -0
  226. data/ext/rugged/vendor/libgit2-dist/tests-clar/commit/parse.c +350 -0
  227. data/ext/rugged/vendor/libgit2-dist/tests-clar/commit/signature.c +65 -0
  228. data/ext/rugged/vendor/libgit2-dist/tests-clar/commit/write.c +140 -0
  229. data/ext/rugged/vendor/libgit2-dist/{tests-clay → tests-clar}/config/add.c +3 -3
  230. data/ext/rugged/vendor/libgit2-dist/tests-clar/config/multivar.c +151 -0
  231. data/ext/rugged/vendor/libgit2-dist/{tests-clay → tests-clar}/config/new.c +5 -5
  232. data/ext/rugged/vendor/libgit2-dist/{tests-clay → tests-clar}/config/read.c +44 -32
  233. data/ext/rugged/vendor/libgit2-dist/tests-clar/config/stress.c +61 -0
  234. data/ext/rugged/vendor/libgit2-dist/{tests-clay → tests-clar}/config/write.c +20 -5
  235. data/ext/rugged/vendor/libgit2-dist/tests-clar/core/buffer.c +613 -0
  236. data/ext/rugged/vendor/libgit2-dist/{tests-clay → tests-clar}/core/dirent.c +39 -26
  237. data/ext/rugged/vendor/libgit2-dist/tests-clar/core/env.c +115 -0
  238. data/ext/rugged/vendor/libgit2-dist/tests-clar/core/errors.c +60 -0
  239. data/ext/rugged/vendor/libgit2-dist/{tests-clay → tests-clar}/core/filebuf.c +4 -18
  240. data/ext/rugged/vendor/libgit2-dist/tests-clar/core/hex.c +22 -0
  241. data/ext/rugged/vendor/libgit2-dist/{tests-clay → tests-clar}/core/oid.c +6 -6
  242. data/ext/rugged/vendor/libgit2-dist/tests-clar/core/path.c +420 -0
  243. data/ext/rugged/vendor/libgit2-dist/tests-clar/core/pool.c +85 -0
  244. data/ext/rugged/vendor/libgit2-dist/tests-clar/core/rmdir.c +68 -0
  245. data/ext/rugged/vendor/libgit2-dist/{tests-clay → tests-clar}/core/string.c +1 -1
  246. data/ext/rugged/vendor/libgit2-dist/tests-clar/core/strmap.c +102 -0
  247. data/ext/rugged/vendor/libgit2-dist/{tests-clay → tests-clar}/core/strtol.c +1 -1
  248. data/ext/rugged/vendor/libgit2-dist/tests-clar/core/vector.c +191 -0
  249. data/ext/rugged/vendor/libgit2-dist/tests-clar/date/date.c +15 -0
  250. data/ext/rugged/vendor/libgit2-dist/tests-clar/diff/blob.c +254 -0
  251. data/ext/rugged/vendor/libgit2-dist/tests-clar/diff/diff_helpers.c +104 -0
  252. data/ext/rugged/vendor/libgit2-dist/tests-clar/diff/diff_helpers.h +47 -0
  253. data/ext/rugged/vendor/libgit2-dist/tests-clar/diff/index.c +92 -0
  254. data/ext/rugged/vendor/libgit2-dist/tests-clar/diff/iterator.c +572 -0
  255. data/ext/rugged/vendor/libgit2-dist/tests-clar/diff/patch.c +99 -0
  256. data/ext/rugged/vendor/libgit2-dist/tests-clar/diff/tree.c +210 -0
  257. data/ext/rugged/vendor/libgit2-dist/tests-clar/diff/workdir.c +543 -0
  258. data/ext/rugged/vendor/libgit2-dist/tests-clar/index/read_tree.c +46 -0
  259. data/ext/rugged/vendor/libgit2-dist/{tests-clay → tests-clar}/index/rename.c +2 -12
  260. data/ext/rugged/vendor/libgit2-dist/tests-clar/index/tests.c +246 -0
  261. data/ext/rugged/vendor/libgit2-dist/tests-clar/network/createremotethenload.c +33 -0
  262. data/ext/rugged/vendor/libgit2-dist/tests-clar/network/remotelocal.c +137 -0
  263. data/ext/rugged/vendor/libgit2-dist/tests-clar/network/remotes.c +183 -0
  264. data/ext/rugged/vendor/libgit2-dist/tests-clar/notes/notes.c +133 -0
  265. data/ext/rugged/vendor/libgit2-dist/tests-clar/notes/notesref.c +57 -0
  266. data/ext/rugged/vendor/libgit2-dist/tests-clar/object/blob/filter.c +125 -0
  267. data/ext/rugged/vendor/libgit2-dist/tests-clar/object/blob/fromchunks.c +87 -0
  268. data/ext/rugged/vendor/libgit2-dist/tests-clar/object/blob/write.c +69 -0
  269. data/ext/rugged/vendor/libgit2-dist/tests-clar/object/commit/commitstagedfile.c +126 -0
  270. data/ext/rugged/vendor/libgit2-dist/tests-clar/object/lookup.c +63 -0
  271. data/ext/rugged/vendor/libgit2-dist/tests-clar/object/message.c +171 -0
  272. data/ext/rugged/vendor/libgit2-dist/{tests-clay → tests-clar}/object/raw/chars.c +3 -14
  273. data/ext/rugged/vendor/libgit2-dist/{tests-clay → tests-clar}/object/raw/compare.c +4 -4
  274. data/ext/rugged/vendor/libgit2-dist/{tests-clay → tests-clar}/object/raw/convert.c +10 -10
  275. data/ext/rugged/vendor/libgit2-dist/{tests-clay → tests-clar}/object/raw/data.h +0 -0
  276. data/ext/rugged/vendor/libgit2-dist/{tests-clay → tests-clar}/object/raw/fromstr.c +1 -1
  277. data/ext/rugged/vendor/libgit2-dist/{tests-clay → tests-clar}/object/raw/hash.c +21 -17
  278. data/ext/rugged/vendor/libgit2-dist/{tests-clay → tests-clar}/object/raw/short.c +1 -1
  279. data/ext/rugged/vendor/libgit2-dist/{tests-clay → tests-clar}/object/raw/size.c +1 -1
  280. data/ext/rugged/vendor/libgit2-dist/{tests-clay → tests-clar}/object/raw/type2string.c +14 -14
  281. data/ext/rugged/vendor/libgit2-dist/tests-clar/object/raw/write.c +455 -0
  282. data/ext/rugged/vendor/libgit2-dist/tests-clar/object/tag/peel.c +56 -0
  283. data/ext/rugged/vendor/libgit2-dist/tests-clar/object/tag/read.c +130 -0
  284. data/ext/rugged/vendor/libgit2-dist/tests-clar/object/tag/write.c +192 -0
  285. data/ext/rugged/vendor/libgit2-dist/{tests-clay → tests-clar}/object/tree/frompath.c +22 -16
  286. data/ext/rugged/vendor/libgit2-dist/tests-clar/object/tree/read.c +75 -0
  287. data/ext/rugged/vendor/libgit2-dist/tests-clar/object/tree/write.c +84 -0
  288. data/ext/rugged/vendor/libgit2-dist/{tests-clay → tests-clar}/odb/loose.c +1 -1
  289. data/ext/rugged/vendor/libgit2-dist/{tests-clay → tests-clar}/odb/loose_data.h +0 -0
  290. data/ext/rugged/vendor/libgit2-dist/tests-clar/odb/mixed.c +24 -0
  291. data/ext/rugged/vendor/libgit2-dist/{tests-clay → tests-clar}/odb/pack_data.h +0 -0
  292. data/ext/rugged/vendor/libgit2-dist/{tests-clay → tests-clar}/odb/packed.c +1 -1
  293. data/ext/rugged/vendor/libgit2-dist/{tests-clay → tests-clar}/odb/sorting.c +1 -1
  294. data/ext/rugged/vendor/libgit2-dist/tests-clar/refs/branches/create.c +113 -0
  295. data/ext/rugged/vendor/libgit2-dist/tests-clar/refs/branches/delete.c +91 -0
  296. data/ext/rugged/vendor/libgit2-dist/tests-clar/refs/branches/listall.c +78 -0
  297. data/ext/rugged/vendor/libgit2-dist/tests-clar/refs/branches/move.c +72 -0
  298. data/ext/rugged/vendor/libgit2-dist/tests-clar/refs/crashes.c +17 -0
  299. data/ext/rugged/vendor/libgit2-dist/tests-clar/refs/create.c +149 -0
  300. data/ext/rugged/vendor/libgit2-dist/tests-clar/refs/delete.c +85 -0
  301. data/ext/rugged/vendor/libgit2-dist/tests-clar/refs/list.c +53 -0
  302. data/ext/rugged/vendor/libgit2-dist/tests-clar/refs/listall.c +36 -0
  303. data/ext/rugged/vendor/libgit2-dist/tests-clar/refs/lookup.c +42 -0
  304. data/ext/rugged/vendor/libgit2-dist/tests-clar/refs/normalize.c +200 -0
  305. data/ext/rugged/vendor/libgit2-dist/tests-clar/refs/overwrite.c +136 -0
  306. data/ext/rugged/vendor/libgit2-dist/tests-clar/refs/pack.c +67 -0
  307. data/ext/rugged/vendor/libgit2-dist/tests-clar/refs/read.c +194 -0
  308. data/ext/rugged/vendor/libgit2-dist/tests-clar/refs/reflog.c +123 -0
  309. data/ext/rugged/vendor/libgit2-dist/tests-clar/refs/rename.c +339 -0
  310. data/ext/rugged/vendor/libgit2-dist/tests-clar/refs/revparse.c +174 -0
  311. data/ext/rugged/vendor/libgit2-dist/tests-clar/refs/unicode.c +42 -0
  312. data/ext/rugged/vendor/libgit2-dist/tests-clar/repo/discover.c +142 -0
  313. data/ext/rugged/vendor/libgit2-dist/{tests-clay → tests-clar}/repo/getters.c +19 -1
  314. data/ext/rugged/vendor/libgit2-dist/tests-clar/repo/init.c +235 -0
  315. data/ext/rugged/vendor/libgit2-dist/tests-clar/repo/open.c +282 -0
  316. data/ext/rugged/vendor/libgit2-dist/tests-clar/repo/setters.c +80 -0
  317. data/ext/rugged/vendor/libgit2-dist/tests-clar/reset/mixed.c +47 -0
  318. data/ext/rugged/vendor/libgit2-dist/tests-clar/reset/reset_helpers.c +10 -0
  319. data/ext/rugged/vendor/libgit2-dist/tests-clar/reset/reset_helpers.h +6 -0
  320. data/ext/rugged/vendor/libgit2-dist/tests-clar/reset/soft.c +102 -0
  321. data/ext/rugged/vendor/libgit2-dist/{tests/t05-revwalk.c → tests-clar/revwalk/basic.c} +85 -44
  322. data/ext/rugged/vendor/libgit2-dist/tests-clar/revwalk/mergebase.c +148 -0
  323. data/ext/rugged/vendor/libgit2-dist/tests-clar/status/ignore.c +133 -0
  324. data/ext/rugged/vendor/libgit2-dist/{tests-clay → tests-clar}/status/single.c +2 -11
  325. data/ext/rugged/vendor/libgit2-dist/tests-clar/status/status_data.h +202 -0
  326. data/ext/rugged/vendor/libgit2-dist/tests-clar/status/status_helpers.c +49 -0
  327. data/ext/rugged/vendor/libgit2-dist/tests-clar/status/status_helpers.h +33 -0
  328. data/ext/rugged/vendor/libgit2-dist/tests-clar/status/submodules.c +112 -0
  329. data/ext/rugged/vendor/libgit2-dist/tests-clar/status/worktree.c +649 -0
  330. data/ext/rugged/vendor/libgit2-dist/tests-clar/threads/basic.c +20 -0
  331. data/ext/rugged/vendor/libgit2-dist.tar.gz +0 -0
  332. data/lib/rugged/commit.rb +35 -0
  333. data/lib/rugged/object.rb +7 -0
  334. data/lib/rugged/reference.rb +9 -0
  335. data/lib/rugged/repository.rb +99 -3
  336. data/lib/rugged/tag.rb +22 -0
  337. data/lib/rugged/tree.rb +8 -0
  338. data/lib/rugged/version.rb +1 -1
  339. data/lib/rugged.rb +4 -1
  340. data/test/blob_test.rb +2 -2
  341. data/test/commit_test.rb +27 -13
  342. data/test/config_test.rb +44 -0
  343. data/test/coverage/HEAD.json +1 -1
  344. data/test/fixtures/testrepo.git/config +2 -0
  345. data/test/fixtures/testrepo.git/objects/7f/043268ea43ce18e3540acaabf9e090c91965b0 +0 -0
  346. data/test/lib_test.rb +7 -0
  347. data/test/object_test.rb +3 -3
  348. data/test/reference_test.rb +46 -8
  349. data/test/remote_test.rb +8 -2
  350. data/test/repo_pack_test.rb +3 -3
  351. data/test/repo_test.rb +79 -11
  352. data/test/tag_test.rb +9 -2
  353. data/test/test_helper.rb +21 -0
  354. data/test/tree_test.rb +18 -6
  355. metadata +205 -81
  356. data/ext/rugged/vendor/libgit2-dist/include/git2/zlib.h +0 -40
  357. data/ext/rugged/vendor/libgit2-dist/src/hashtable.c +0 -243
  358. data/ext/rugged/vendor/libgit2-dist/src/hashtable.h +0 -80
  359. data/ext/rugged/vendor/libgit2-dist/tests/t00-core.c +0 -628
  360. data/ext/rugged/vendor/libgit2-dist/tests/t01-data.h +0 -322
  361. data/ext/rugged/vendor/libgit2-dist/tests/t01-rawobj.c +0 -638
  362. data/ext/rugged/vendor/libgit2-dist/tests/t03-data.h +0 -344
  363. data/ext/rugged/vendor/libgit2-dist/tests/t03-objwrite.c +0 -255
  364. data/ext/rugged/vendor/libgit2-dist/tests/t04-commit.c +0 -788
  365. data/ext/rugged/vendor/libgit2-dist/tests/t06-index.c +0 -219
  366. data/ext/rugged/vendor/libgit2-dist/tests/t07-hashtable.c +0 -192
  367. data/ext/rugged/vendor/libgit2-dist/tests/t08-tag.c +0 -357
  368. data/ext/rugged/vendor/libgit2-dist/tests/t09-tree.c +0 -221
  369. data/ext/rugged/vendor/libgit2-dist/tests/t10-refs.c +0 -1294
  370. data/ext/rugged/vendor/libgit2-dist/tests/t12-repo.c +0 -174
  371. data/ext/rugged/vendor/libgit2-dist/tests/t13-threads.c +0 -41
  372. data/ext/rugged/vendor/libgit2-dist/tests/t17-bufs.c +0 -61
  373. data/ext/rugged/vendor/libgit2-dist/tests/t18-status.c +0 -448
  374. data/ext/rugged/vendor/libgit2-dist/tests/test_helpers.c +0 -310
  375. data/ext/rugged/vendor/libgit2-dist/tests/test_helpers.h +0 -83
  376. data/ext/rugged/vendor/libgit2-dist/tests/test_lib.c +0 -198
  377. data/ext/rugged/vendor/libgit2-dist/tests/test_lib.h +0 -54
  378. data/ext/rugged/vendor/libgit2-dist/tests/test_main.c +0 -89
  379. data/ext/rugged/vendor/libgit2-dist/tests-clay/clay.h +0 -187
  380. data/ext/rugged/vendor/libgit2-dist/tests-clay/clay_libgit2.h +0 -28
  381. data/ext/rugged/vendor/libgit2-dist/tests-clay/clay_main.c +0 -1073
  382. data/ext/rugged/vendor/libgit2-dist/tests-clay/config/stress.c +0 -39
  383. data/ext/rugged/vendor/libgit2-dist/tests-clay/core/path.c +0 -139
  384. data/ext/rugged/vendor/libgit2-dist/tests-clay/core/rmdir.c +0 -50
  385. data/ext/rugged/vendor/libgit2-dist/tests-clay/core/vector.c +0 -66
  386. data/ext/rugged/vendor/libgit2-dist/tests-clay/network/remotes.c +0 -50
  387. data/ext/rugged/vendor/libgit2-dist/tests-clay/repo/init.c +0 -104
  388. data/ext/rugged/vendor/libgit2-dist/tests-clay/repo/open.c +0 -54
  389. data/ext/rugged/vendor/libgit2-dist/tests-clay/status/status_data.h +0 -48
  390. data/ext/rugged/vendor/libgit2-dist/tests-clay/status/worktree.c +0 -124
  391. data/lib/rugged/objects.rb +0 -45
  392. data/test/fixtures/testrepo.git/refs/heads/new_name +0 -1
@@ -0,0 +1,753 @@
1
+ /*
2
+ * Copyright (C) 2009-2012 the libgit2 contributors
3
+ *
4
+ * This file is part of libgit2, distributed under the GNU GPL v2 with
5
+ * a Linking Exception. For full terms see the included COPYING file.
6
+ */
7
+
8
+ #include <assert.h>
9
+
10
+ #include "common.h"
11
+ #include "buffer.h"
12
+ #include "tree.h"
13
+
14
+ #include "git2.h"
15
+
16
+ GIT_BEGIN_DECL
17
+
18
+ typedef enum {
19
+ REVPARSE_STATE_INIT,
20
+ REVPARSE_STATE_CARET,
21
+ REVPARSE_STATE_LINEAR,
22
+ REVPARSE_STATE_COLON,
23
+ REVPARSE_STATE_DONE,
24
+ } revparse_state;
25
+
26
+ static void set_invalid_syntax_err(const char *spec)
27
+ {
28
+ giterr_set(GITERR_INVALID, "Refspec '%s' is not valid.", spec);
29
+ }
30
+
31
+ static int revparse_lookup_fully_qualifed_ref(git_object **out, git_repository *repo, const char*spec)
32
+ {
33
+ git_oid resolved;
34
+
35
+ if (git_reference_name_to_oid(&resolved, repo, spec) < 0)
36
+ return GIT_ERROR;
37
+
38
+ return git_object_lookup(out, repo, &resolved, GIT_OBJ_ANY);
39
+ }
40
+
41
+ /* Returns non-zero if yes */
42
+ static int spec_looks_like_describe_output(const char *spec)
43
+ {
44
+ regex_t regex;
45
+ int regex_error, retcode;
46
+
47
+ regex_error = regcomp(&regex, ".+-[0-9]+-g[0-9a-fA-F]+", REG_EXTENDED);
48
+ if (regex_error != 0) {
49
+ giterr_set_regex(&regex, regex_error);
50
+ return 1; /* To be safe */
51
+ }
52
+ retcode = regexec(&regex, spec, 0, NULL, 0);
53
+ regfree(&regex);
54
+ return retcode == 0;
55
+ }
56
+
57
+ static int revparse_lookup_object(git_object **out, git_repository *repo, const char *spec)
58
+ {
59
+ size_t speclen = strlen(spec);
60
+ git_object *obj = NULL;
61
+ git_oid oid;
62
+ git_buf refnamebuf = GIT_BUF_INIT;
63
+ static const char* formatters[] = {
64
+ "refs/%s",
65
+ "refs/tags/%s",
66
+ "refs/heads/%s",
67
+ "refs/remotes/%s",
68
+ "refs/remotes/%s/HEAD",
69
+ NULL
70
+ };
71
+ unsigned int i;
72
+ const char *substr;
73
+
74
+ /* "git describe" output; snip everything before/including "-g" */
75
+ substr = strstr(spec, "-g");
76
+ if (substr &&
77
+ spec_looks_like_describe_output(spec) &&
78
+ !revparse_lookup_object(out, repo, substr+2)) {
79
+ return 0;
80
+ }
81
+
82
+ /* SHA or prefix */
83
+ if (!git_oid_fromstrn(&oid, spec, speclen)) {
84
+ if (!git_object_lookup_prefix(&obj, repo, &oid, speclen, GIT_OBJ_ANY)) {
85
+ *out = obj;
86
+ return 0;
87
+ }
88
+ }
89
+
90
+ /* Fully-named ref */
91
+ if (!revparse_lookup_fully_qualifed_ref(&obj, repo, spec)) {
92
+ *out = obj;
93
+ return 0;
94
+ }
95
+
96
+ /* Partially-named ref; match in this order: */
97
+ for (i=0; formatters[i]; i++) {
98
+ git_buf_clear(&refnamebuf);
99
+ if (git_buf_printf(&refnamebuf, formatters[i], spec) < 0) {
100
+ return GIT_ERROR;
101
+ }
102
+
103
+ if (!revparse_lookup_fully_qualifed_ref(&obj, repo, git_buf_cstr(&refnamebuf))) {
104
+ git_buf_free(&refnamebuf);
105
+ *out = obj;
106
+ return 0;
107
+ }
108
+ }
109
+ git_buf_free(&refnamebuf);
110
+
111
+ giterr_set(GITERR_REFERENCE, "Refspec '%s' not found.", spec);
112
+ return GIT_ERROR;
113
+ }
114
+
115
+
116
+ static int all_chars_are_digits(const char *str, size_t len)
117
+ {
118
+ size_t i=0;
119
+ for (i=0; i<len; i++) {
120
+ if (str[i] < '0' || str[i] > '9') return 0;
121
+ }
122
+ return 1;
123
+ }
124
+
125
+ static void normalize_maybe_empty_refname(git_buf *buf, git_repository *repo, const char *refspec, size_t refspeclen)
126
+ {
127
+ git_reference *ref;
128
+
129
+ if (!refspeclen) {
130
+ /* Empty refspec means current branch (target of HEAD) */
131
+ git_reference_lookup(&ref, repo, "HEAD");
132
+ git_buf_puts(buf, git_reference_target(ref));
133
+ git_reference_free(ref);
134
+ } else if (strstr(refspec, "HEAD")) {
135
+ /* Explicit head */
136
+ git_buf_puts(buf, refspec);
137
+ }else {
138
+ if (git__prefixcmp(refspec, "refs/heads/") != 0) {
139
+ git_buf_printf(buf, "refs/heads/%s", refspec);
140
+ } else {
141
+ git_buf_puts(buf, refspec);
142
+ }
143
+ }
144
+ }
145
+
146
+ static int walk_ref_history(git_object **out, git_repository *repo, const char *refspec, const char *reflogspec)
147
+ {
148
+ git_reference *ref;
149
+ git_reflog *reflog = NULL;
150
+ int n, retcode = GIT_ERROR;
151
+ int i, refloglen;
152
+ const git_reflog_entry *entry;
153
+ git_buf buf = GIT_BUF_INIT;
154
+ size_t refspeclen = strlen(refspec);
155
+ size_t reflogspeclen = strlen(reflogspec);
156
+
157
+ if (git__prefixcmp(reflogspec, "@{") != 0 ||
158
+ git__suffixcmp(reflogspec, "}") != 0) {
159
+ giterr_set(GITERR_INVALID, "Bad reflogspec '%s'", reflogspec);
160
+ return GIT_ERROR;
161
+ }
162
+
163
+ /* "@{-N}" form means walk back N checkouts. That means the HEAD log. */
164
+ if (refspeclen == 0 && !git__prefixcmp(reflogspec, "@{-")) {
165
+ regex_t regex;
166
+ int regex_error;
167
+
168
+ if (git__strtol32(&n, reflogspec+3, NULL, 0) < 0 ||
169
+ n < 1) {
170
+ giterr_set(GITERR_INVALID, "Invalid reflogspec %s", reflogspec);
171
+ return GIT_ERROR;
172
+ }
173
+
174
+ if (!git_reference_lookup(&ref, repo, "HEAD")) {
175
+ if (!git_reflog_read(&reflog, ref)) {
176
+ regex_error = regcomp(&regex, "checkout: moving from (.*) to .*", REG_EXTENDED);
177
+ if (regex_error != 0) {
178
+ giterr_set_regex(&regex, regex_error);
179
+ } else {
180
+ regmatch_t regexmatches[2];
181
+
182
+ refloglen = git_reflog_entrycount(reflog);
183
+ for (i=refloglen-1; i >= 0; i--) {
184
+ const char *msg;
185
+ entry = git_reflog_entry_byindex(reflog, i);
186
+
187
+ msg = git_reflog_entry_msg(entry);
188
+ if (!regexec(&regex, msg, 2, regexmatches, 0)) {
189
+ n--;
190
+ if (!n) {
191
+ git_buf_put(&buf, msg+regexmatches[1].rm_so, regexmatches[1].rm_eo - regexmatches[1].rm_so);
192
+ retcode = revparse_lookup_object(out, repo, git_buf_cstr(&buf));
193
+ break;
194
+ }
195
+ }
196
+ }
197
+ regfree(&regex);
198
+ }
199
+ }
200
+ git_reference_free(ref);
201
+ }
202
+ } else {
203
+ int date_error = 0;
204
+ git_time_t timestamp;
205
+ git_buf datebuf = GIT_BUF_INIT;
206
+
207
+ git_buf_put(&datebuf, reflogspec+2, reflogspeclen-3);
208
+ date_error = git__date_parse(&timestamp, git_buf_cstr(&datebuf));
209
+
210
+ /* @{u} or @{upstream} -> upstream branch, for a tracking branch. This is stored in the config. */
211
+ if (!strcmp(reflogspec, "@{u}") || !strcmp(reflogspec, "@{upstream}")) {
212
+ git_config *cfg;
213
+ if (!git_repository_config(&cfg, repo)) {
214
+ /* Is the ref a tracking branch? */
215
+ const char *remote;
216
+ git_buf_clear(&buf);
217
+ git_buf_printf(&buf, "branch.%s.remote", refspec);
218
+ if (!git_config_get_string(&remote, cfg, git_buf_cstr(&buf))) {
219
+ /* Yes. Find the first merge target name. */
220
+ const char *mergetarget;
221
+ git_buf_clear(&buf);
222
+ git_buf_printf(&buf, "branch.%s.merge", refspec);
223
+ if (!git_config_get_string(&mergetarget, cfg, git_buf_cstr(&buf)) &&
224
+ !git__prefixcmp(mergetarget, "refs/heads/")) {
225
+ /* Success. Look up the target and fetch the object. */
226
+ git_buf_clear(&buf);
227
+ git_buf_printf(&buf, "refs/remotes/%s/%s", remote, mergetarget+11);
228
+ retcode = revparse_lookup_fully_qualifed_ref(out, repo, git_buf_cstr(&buf));
229
+ }
230
+ }
231
+ git_config_free(cfg);
232
+ }
233
+ }
234
+
235
+ /* @{N} -> Nth prior value for the ref (from reflog) */
236
+ else if (all_chars_are_digits(reflogspec+2, reflogspeclen-3) &&
237
+ !git__strtol32(&n, reflogspec+2, NULL, 0) &&
238
+ n <= 100000000) { /* Allow integer time */
239
+ normalize_maybe_empty_refname(&buf, repo, refspec, refspeclen);
240
+
241
+ if (n == 0) {
242
+ retcode = revparse_lookup_fully_qualifed_ref(out, repo, git_buf_cstr(&buf));
243
+ } else if (!git_reference_lookup(&ref, repo, git_buf_cstr(&buf))) {
244
+ if (!git_reflog_read(&reflog, ref)) {
245
+ int numentries = git_reflog_entrycount(reflog);
246
+ if (numentries < n) {
247
+ giterr_set(GITERR_REFERENCE, "Reflog for '%s' has only %d entries, asked for %d",
248
+ git_buf_cstr(&buf), numentries, n);
249
+ retcode = GIT_ERROR;
250
+ } else {
251
+ const git_reflog_entry *entry = git_reflog_entry_byindex(reflog, n);
252
+ const git_oid *oid = git_reflog_entry_oidold(entry);
253
+ retcode = git_object_lookup(out, repo, oid, GIT_OBJ_ANY);
254
+ }
255
+ }
256
+ git_reference_free(ref);
257
+ }
258
+ }
259
+
260
+ else if (!date_error) {
261
+ /* Ref as it was on a certain date */
262
+ normalize_maybe_empty_refname(&buf, repo, refspec, refspeclen);
263
+
264
+ if (!git_reference_lookup(&ref, repo, git_buf_cstr(&buf))) {
265
+ git_reflog *reflog;
266
+ if (!git_reflog_read(&reflog, ref)) {
267
+ /* Keep walking until we find an entry older than the given date */
268
+ int numentries = git_reflog_entrycount(reflog);
269
+ int i;
270
+
271
+ /* TODO: clunky. Factor "now" into a utility */
272
+ git_signature *sig;
273
+ git_time as_of;
274
+
275
+ git_signature_now(&sig, "blah", "blah");
276
+ as_of = sig->when;
277
+ git_signature_free(sig);
278
+
279
+ as_of.time = (timestamp > 0)
280
+ ? timestamp
281
+ : sig->when.time + timestamp;
282
+
283
+ for (i=numentries-1; i>0; i--) {
284
+ const git_reflog_entry *entry = git_reflog_entry_byindex(reflog, i);
285
+ git_time commit_time = git_reflog_entry_committer(entry)->when;
286
+ if (git__time_cmp(&commit_time, &as_of) <= 0 ) {
287
+ retcode = git_object_lookup(out, repo, git_reflog_entry_oidnew(entry), GIT_OBJ_ANY);
288
+ break;
289
+ }
290
+ }
291
+
292
+ if (!i) {
293
+ /* Didn't find a match. Use the oldest revision in the reflog. */
294
+ const git_reflog_entry *entry = git_reflog_entry_byindex(reflog, 0);
295
+ retcode = git_object_lookup(out, repo, git_reflog_entry_oidnew(entry), GIT_OBJ_ANY);
296
+ }
297
+
298
+ git_reflog_free(reflog);
299
+ }
300
+
301
+ git_reference_free(ref);
302
+ }
303
+ }
304
+
305
+ git_buf_free(&datebuf);
306
+ }
307
+
308
+ if (reflog) git_reflog_free(reflog);
309
+ git_buf_free(&buf);
310
+ return retcode;
311
+ }
312
+
313
+ static git_object* dereference_object(git_object *obj)
314
+ {
315
+ git_otype type = git_object_type(obj);
316
+
317
+ switch (type) {
318
+ case GIT_OBJ_COMMIT:
319
+ {
320
+ git_tree *tree = NULL;
321
+ if (0 == git_commit_tree(&tree, (git_commit*)obj)) {
322
+ return (git_object*)tree;
323
+ }
324
+ }
325
+ break;
326
+ case GIT_OBJ_TAG:
327
+ {
328
+ git_object *newobj = NULL;
329
+ if (0 == git_tag_target(&newobj, (git_tag*)obj)) {
330
+ return newobj;
331
+ }
332
+ }
333
+ break;
334
+
335
+ default:
336
+ case GIT_OBJ_TREE:
337
+ case GIT_OBJ_BLOB:
338
+ case GIT_OBJ_OFS_DELTA:
339
+ case GIT_OBJ_REF_DELTA:
340
+ break;
341
+ }
342
+
343
+ /* Can't dereference some types */
344
+ return NULL;
345
+ }
346
+
347
+ static int dereference_to_type(git_object **out, git_object *obj, git_otype target_type)
348
+ {
349
+ int retcode = 1;
350
+ git_object *obj1 = obj, *obj2 = obj;
351
+
352
+ while (retcode > 0) {
353
+ git_otype this_type = git_object_type(obj1);
354
+
355
+ if (this_type == target_type) {
356
+ *out = obj1;
357
+ retcode = 0;
358
+ } else {
359
+ /* Dereference once, if possible. */
360
+ obj2 = dereference_object(obj1);
361
+ if (!obj2) {
362
+ giterr_set(GITERR_REFERENCE, "Can't dereference to type");
363
+ retcode = GIT_ERROR;
364
+ }
365
+ }
366
+ if (obj1 != obj && obj1 != obj2) {
367
+ git_object_free(obj1);
368
+ }
369
+ obj1 = obj2;
370
+ }
371
+ return retcode;
372
+ }
373
+
374
+ static git_otype parse_obj_type(const char *str)
375
+ {
376
+ if (!strcmp(str, "{commit}")) return GIT_OBJ_COMMIT;
377
+ if (!strcmp(str, "{tree}")) return GIT_OBJ_TREE;
378
+ if (!strcmp(str, "{blob}")) return GIT_OBJ_BLOB;
379
+ if (!strcmp(str, "{tag}")) return GIT_OBJ_TAG;
380
+ return GIT_OBJ_BAD;
381
+ }
382
+
383
+ static int handle_caret_syntax(git_object **out, git_repository *repo, git_object *obj, const char *movement)
384
+ {
385
+ git_commit *commit;
386
+ size_t movementlen = strlen(movement);
387
+ int n;
388
+
389
+ if (*movement == '{') {
390
+ if (movement[movementlen-1] != '}') {
391
+ set_invalid_syntax_err(movement);
392
+ return GIT_ERROR;
393
+ }
394
+
395
+ /* {} -> Dereference until we reach an object that isn't a tag. */
396
+ if (movementlen == 2) {
397
+ git_object *newobj = obj;
398
+ git_object *newobj2 = newobj;
399
+ while (git_object_type(newobj2) == GIT_OBJ_TAG) {
400
+ newobj2 = dereference_object(newobj);
401
+ if (newobj != obj) git_object_free(newobj);
402
+ if (!newobj2) {
403
+ giterr_set(GITERR_REFERENCE, "Couldn't find object of target type.");
404
+ return GIT_ERROR;
405
+ }
406
+ newobj = newobj2;
407
+ }
408
+ *out = newobj2;
409
+ return 0;
410
+ }
411
+
412
+ /* {/...} -> Walk all commits until we see a commit msg that matches the phrase. */
413
+ if (movement[1] == '/') {
414
+ int retcode = GIT_ERROR;
415
+ git_revwalk *walk;
416
+ if (!git_revwalk_new(&walk, repo)) {
417
+ git_oid oid;
418
+ regex_t preg;
419
+ int reg_error;
420
+ git_buf buf = GIT_BUF_INIT;
421
+
422
+ git_revwalk_sorting(walk, GIT_SORT_TIME);
423
+ git_revwalk_push(walk, git_object_id(obj));
424
+
425
+ /* Extract the regex from the movement string */
426
+ git_buf_put(&buf, movement+2, strlen(movement)-3);
427
+
428
+ reg_error = regcomp(&preg, git_buf_cstr(&buf), REG_EXTENDED);
429
+ if (reg_error != 0) {
430
+ giterr_set_regex(&preg, reg_error);
431
+ } else {
432
+ while(!git_revwalk_next(&oid, walk)) {
433
+ git_object *walkobj;
434
+
435
+ /* Fetch the commit object, and check for matches in the message */
436
+ if (!git_object_lookup(&walkobj, repo, &oid, GIT_OBJ_COMMIT)) {
437
+ if (!regexec(&preg, git_commit_message((git_commit*)walkobj), 0, NULL, 0)) {
438
+ /* Found it! */
439
+ retcode = 0;
440
+ *out = walkobj;
441
+ if (obj == walkobj) {
442
+ /* Avoid leaking an object */
443
+ git_object_free(walkobj);
444
+ }
445
+ break;
446
+ }
447
+ git_object_free(walkobj);
448
+ }
449
+ }
450
+ if (retcode < 0) {
451
+ giterr_set(GITERR_REFERENCE, "Couldn't find a match for %s", movement);
452
+ }
453
+ regfree(&preg);
454
+ }
455
+
456
+ git_buf_free(&buf);
457
+ git_revwalk_free(walk);
458
+ }
459
+ return retcode;
460
+ }
461
+
462
+ /* {...} -> Dereference until we reach an object of a certain type. */
463
+ if (dereference_to_type(out, obj, parse_obj_type(movement)) < 0) {
464
+ return GIT_ERROR;
465
+ }
466
+ return 0;
467
+ }
468
+
469
+ /* Dereference until we reach a commit. */
470
+ if (dereference_to_type(&obj, obj, GIT_OBJ_COMMIT) < 0) {
471
+ /* Can't dereference to a commit; fail */
472
+ return GIT_ERROR;
473
+ }
474
+
475
+ /* "^" is the same as "^1" */
476
+ if (movementlen == 0) {
477
+ n = 1;
478
+ } else {
479
+ git__strtol32(&n, movement, NULL, 0);
480
+ }
481
+ commit = (git_commit*)obj;
482
+
483
+ /* "^0" just returns the input */
484
+ if (n == 0) {
485
+ *out = obj;
486
+ return 0;
487
+ }
488
+
489
+ if (git_commit_parent(&commit, commit, n-1) < 0) {
490
+ return GIT_ERROR;
491
+ }
492
+
493
+ *out = (git_object*)commit;
494
+ return 0;
495
+ }
496
+
497
+ static int handle_linear_syntax(git_object **out, git_object *obj, const char *movement)
498
+ {
499
+ git_commit *commit1, *commit2;
500
+ int i, n;
501
+
502
+ /* Dereference until we reach a commit. */
503
+ if (dereference_to_type(&obj, obj, GIT_OBJ_COMMIT) < 0) {
504
+ /* Can't dereference to a commit; fail */
505
+ return GIT_ERROR;
506
+ }
507
+
508
+ /* "~" is the same as "~1" */
509
+ if (*movement == '\0') {
510
+ n = 1;
511
+ } else {
512
+ git__strtol32(&n, movement, NULL, 0);
513
+ }
514
+ commit1 = (git_commit*)obj;
515
+
516
+ /* "~0" just returns the input */
517
+ if (n == 0) {
518
+ *out = obj;
519
+ return 0;
520
+ }
521
+
522
+ for (i=0; i<n; i++) {
523
+ if (git_commit_parent(&commit2, commit1, 0) < 0) {
524
+ return GIT_ERROR;
525
+ }
526
+ if (commit1 != (git_commit*)obj) {
527
+ git_commit_free(commit1);
528
+ }
529
+ commit1 = commit2;
530
+ }
531
+
532
+ *out = (git_object*)commit1;
533
+ return 0;
534
+ }
535
+
536
+ static int oid_for_tree_path(git_oid *out, git_tree *tree, git_repository *repo, const char *path)
537
+ {
538
+ char *str = git__strdup(path);
539
+ char *tok;
540
+ void *alloc = str;
541
+ git_tree *tree2 = tree;
542
+ const git_tree_entry *entry;
543
+
544
+ while ((tok = git__strtok(&str, "/\\")) != NULL) {
545
+ entry = git_tree_entry_byname(tree2, tok);
546
+ if (tree2 != tree) git_tree_free(tree2);
547
+ if (git_tree_entry__is_tree(entry)) {
548
+ if (git_tree_lookup(&tree2, repo, &entry->oid) < 0) {
549
+ git__free(alloc);
550
+ return GIT_ERROR;
551
+ }
552
+ }
553
+ }
554
+
555
+ git_oid_cpy(out, git_tree_entry_id(entry));
556
+ git__free(alloc);
557
+ return 0;
558
+ }
559
+
560
+ static int handle_colon_syntax(git_object **out,
561
+ git_repository *repo,
562
+ git_object *obj,
563
+ const char *path)
564
+ {
565
+ git_tree *tree;
566
+ git_oid oid;
567
+
568
+ /* Dereference until we reach a tree. */
569
+ if (dereference_to_type(&obj, obj, GIT_OBJ_TREE) < 0) {
570
+ return GIT_ERROR;
571
+ }
572
+ tree = (git_tree*)obj;
573
+
574
+ /* Find the blob at the given path. */
575
+ oid_for_tree_path(&oid, tree, repo, path);
576
+ git_tree_free(tree);
577
+ return git_object_lookup(out, repo, &oid, GIT_OBJ_ANY);
578
+ }
579
+
580
+ static int revparse_global_grep(git_object **out, git_repository *repo, const char *pattern)
581
+ {
582
+ git_revwalk *walk;
583
+ int retcode = GIT_ERROR;
584
+
585
+ if (!pattern[0]) {
586
+ giterr_set(GITERR_REGEX, "Empty pattern");
587
+ return GIT_ERROR;
588
+ }
589
+
590
+ if (!git_revwalk_new(&walk, repo)) {
591
+ regex_t preg;
592
+ int reg_error;
593
+ git_oid oid;
594
+
595
+ git_revwalk_sorting(walk, GIT_SORT_TIME);
596
+ git_revwalk_push_glob(walk, "refs/heads/*");
597
+
598
+ reg_error = regcomp(&preg, pattern, REG_EXTENDED);
599
+ if (reg_error != 0) {
600
+ giterr_set_regex(&preg, reg_error);
601
+ } else {
602
+ git_object *walkobj = NULL, *resultobj = NULL;
603
+ while(!git_revwalk_next(&oid, walk)) {
604
+ /* Fetch the commit object, and check for matches in the message */
605
+ if (walkobj != resultobj) git_object_free(walkobj);
606
+ if (!git_object_lookup(&walkobj, repo, &oid, GIT_OBJ_COMMIT)) {
607
+ if (!regexec(&preg, git_commit_message((git_commit*)walkobj), 0, NULL, 0)) {
608
+ /* Match! */
609
+ resultobj = walkobj;
610
+ retcode = 0;
611
+ break;
612
+ }
613
+ }
614
+ }
615
+ if (!resultobj) {
616
+ giterr_set(GITERR_REFERENCE, "Couldn't find a match for %s", pattern);
617
+ } else {
618
+ *out = resultobj;
619
+ }
620
+ regfree(&preg);
621
+ git_revwalk_free(walk);
622
+ }
623
+ }
624
+
625
+ return retcode;
626
+ }
627
+
628
+ int git_revparse_single(git_object **out, git_repository *repo, const char *spec)
629
+ {
630
+ revparse_state current_state = REVPARSE_STATE_INIT, next_state = REVPARSE_STATE_INIT;
631
+ const char *spec_cur = spec;
632
+ git_object *cur_obj = NULL, *next_obj = NULL;
633
+ git_buf specbuffer = GIT_BUF_INIT, stepbuffer = GIT_BUF_INIT;
634
+ int retcode = 0;
635
+
636
+ assert(out && repo && spec);
637
+
638
+ if (spec[0] == ':') {
639
+ if (spec[1] == '/') {
640
+ return revparse_global_grep(out, repo, spec+2);
641
+ }
642
+ /* TODO: support merge-stage path lookup (":2:Makefile"). */
643
+ giterr_set(GITERR_INVALID, "Unimplemented");
644
+ return GIT_ERROR;
645
+ }
646
+
647
+ while (current_state != REVPARSE_STATE_DONE) {
648
+ switch (current_state) {
649
+ case REVPARSE_STATE_INIT:
650
+ if (!*spec_cur) {
651
+ /* No operators, just a name. Find it and return. */
652
+ retcode = revparse_lookup_object(out, repo, spec);
653
+ next_state = REVPARSE_STATE_DONE;
654
+ } else if (*spec_cur == '@') {
655
+ /* '@' syntax doesn't allow chaining */
656
+ git_buf_puts(&stepbuffer, spec_cur);
657
+ retcode = walk_ref_history(out, repo, git_buf_cstr(&specbuffer), git_buf_cstr(&stepbuffer));
658
+ next_state = REVPARSE_STATE_DONE;
659
+ } else if (*spec_cur == '^') {
660
+ next_state = REVPARSE_STATE_CARET;
661
+ } else if (*spec_cur == '~') {
662
+ next_state = REVPARSE_STATE_LINEAR;
663
+ } else if (*spec_cur == ':') {
664
+ next_state = REVPARSE_STATE_COLON;
665
+ } else {
666
+ git_buf_putc(&specbuffer, *spec_cur);
667
+ }
668
+ spec_cur++;
669
+
670
+ if (current_state != next_state && next_state != REVPARSE_STATE_DONE) {
671
+ /* Leaving INIT state, find the object specified, in case that state needs it */
672
+ if (revparse_lookup_object(&next_obj, repo, git_buf_cstr(&specbuffer)) < 0) {
673
+ retcode = GIT_ERROR;
674
+ next_state = REVPARSE_STATE_DONE;
675
+ }
676
+ }
677
+ break;
678
+
679
+
680
+ case REVPARSE_STATE_CARET:
681
+ /* Gather characters until NULL, '~', or '^' */
682
+ if (!*spec_cur) {
683
+ retcode = handle_caret_syntax(out, repo, cur_obj, git_buf_cstr(&stepbuffer));
684
+ next_state = REVPARSE_STATE_DONE;
685
+ } else if (*spec_cur == '~') {
686
+ retcode = handle_caret_syntax(&next_obj, repo, cur_obj, git_buf_cstr(&stepbuffer));
687
+ git_buf_clear(&stepbuffer);
688
+ next_state = !retcode ? REVPARSE_STATE_LINEAR : REVPARSE_STATE_DONE;
689
+ } else if (*spec_cur == '^') {
690
+ retcode = handle_caret_syntax(&next_obj, repo, cur_obj, git_buf_cstr(&stepbuffer));
691
+ git_buf_clear(&stepbuffer);
692
+ if (retcode < 0) {
693
+ next_state = REVPARSE_STATE_DONE;
694
+ }
695
+ } else {
696
+ git_buf_putc(&stepbuffer, *spec_cur);
697
+ }
698
+ spec_cur++;
699
+ break;
700
+
701
+ case REVPARSE_STATE_LINEAR:
702
+ if (!*spec_cur) {
703
+ retcode = handle_linear_syntax(out, cur_obj, git_buf_cstr(&stepbuffer));
704
+ next_state = REVPARSE_STATE_DONE;
705
+ } else if (*spec_cur == '~') {
706
+ retcode = handle_linear_syntax(&next_obj, cur_obj, git_buf_cstr(&stepbuffer));
707
+ git_buf_clear(&stepbuffer);
708
+ if (retcode < 0) {
709
+ next_state = REVPARSE_STATE_DONE;
710
+ }
711
+ } else if (*spec_cur == '^') {
712
+ retcode = handle_linear_syntax(&next_obj, cur_obj, git_buf_cstr(&stepbuffer));
713
+ git_buf_clear(&stepbuffer);
714
+ next_state = !retcode ? REVPARSE_STATE_CARET : REVPARSE_STATE_DONE;
715
+ } else {
716
+ git_buf_putc(&stepbuffer, *spec_cur);
717
+ }
718
+ spec_cur++;
719
+ break;
720
+
721
+ case REVPARSE_STATE_COLON:
722
+ if (*spec_cur) {
723
+ git_buf_putc(&stepbuffer, *spec_cur);
724
+ } else {
725
+ retcode = handle_colon_syntax(out, repo, cur_obj, git_buf_cstr(&stepbuffer));
726
+ next_state = REVPARSE_STATE_DONE;
727
+ }
728
+ spec_cur++;
729
+ break;
730
+
731
+ case REVPARSE_STATE_DONE:
732
+ if (cur_obj && *out != cur_obj) git_object_free(cur_obj);
733
+ if (next_obj && *out != next_obj) git_object_free(next_obj);
734
+ break;
735
+ }
736
+
737
+ current_state = next_state;
738
+ if (cur_obj != next_obj) {
739
+ if (cur_obj) git_object_free(cur_obj);
740
+ cur_obj = next_obj;
741
+ }
742
+ }
743
+
744
+ if (*out != cur_obj) git_object_free(cur_obj);
745
+ if (*out != next_obj && next_obj != cur_obj) git_object_free(next_obj);
746
+
747
+ git_buf_free(&specbuffer);
748
+ git_buf_free(&stepbuffer);
749
+ return retcode;
750
+ }
751
+
752
+
753
+ GIT_END_DECL