rugged 0.17.0.b7 → 0.18.0.b1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (310) hide show
  1. data/LICENSE +1 -1
  2. data/README.md +88 -32
  3. data/ext/rugged/extconf.rb +4 -2
  4. data/ext/rugged/rugged.c +72 -10
  5. data/ext/rugged/rugged.h +14 -10
  6. data/ext/rugged/rugged_blob.c +8 -10
  7. data/ext/rugged/rugged_branch.c +11 -14
  8. data/ext/rugged/rugged_commit.c +31 -24
  9. data/ext/rugged/rugged_config.c +2 -2
  10. data/ext/rugged/rugged_index.c +133 -198
  11. data/ext/rugged/rugged_note.c +372 -0
  12. data/ext/rugged/rugged_object.c +50 -22
  13. data/ext/rugged/rugged_reference.c +122 -130
  14. data/ext/rugged/rugged_remote.c +72 -29
  15. data/ext/rugged/rugged_repo.c +402 -20
  16. data/ext/rugged/rugged_revwalk.c +7 -3
  17. data/ext/rugged/rugged_settings.c +110 -0
  18. data/ext/rugged/rugged_signature.c +23 -7
  19. data/ext/rugged/rugged_tag.c +32 -16
  20. data/ext/rugged/rugged_tree.c +44 -15
  21. data/lib/rugged.rb +1 -0
  22. data/lib/rugged/index.rb +8 -0
  23. data/lib/rugged/remote.rb +13 -0
  24. data/lib/rugged/repository.rb +3 -3
  25. data/lib/rugged/version.rb +1 -1
  26. data/test/blob_test.rb +13 -15
  27. data/test/branch_test.rb +32 -67
  28. data/test/commit_test.rb +50 -12
  29. data/test/config_test.rb +12 -11
  30. data/test/coverage/HEAD.json +1 -1
  31. data/test/coverage/cover.rb +40 -21
  32. data/test/errors_test.rb +34 -0
  33. data/test/fixtures/alternate/objects/14/6ae76773c91e3b1d00cf7a338ec55ae58297e2 +0 -0
  34. data/test/fixtures/alternate/objects/14/9c32d47e99d0a3572ff1e70a2e0051bbf347a9 +0 -0
  35. data/test/fixtures/alternate/objects/14/fb3108588f9421bf764041e5e3ac305eb6277f +0 -0
  36. data/test/fixtures/testrepo.git/logs/refs/notes/commits +1 -0
  37. data/test/fixtures/testrepo.git/objects/44/1034f860c1d5d90e4188d11ae0d325176869a8 +1 -0
  38. data/test/fixtures/testrepo.git/objects/60/d415052a33de2150bf68757f6461df4f563ae4 +0 -0
  39. data/test/fixtures/testrepo.git/objects/68/8a8f4ef7496901d15322972f96e212a9e466cc +1 -0
  40. data/test/fixtures/testrepo.git/objects/94/eca2de348d5f672faf56b0decafa5937e3235e +0 -0
  41. data/test/fixtures/testrepo.git/objects/9b/7384fe1676186192842f5d3e129457b62db9e3 +0 -0
  42. data/test/fixtures/testrepo.git/objects/b7/4713326bc972cc15751ed504dca6f6f3b91f7a +3 -0
  43. data/test/fixtures/testrepo.git/refs/notes/commits +1 -0
  44. data/test/index_test.rb +65 -69
  45. data/test/lib_test.rb +76 -11
  46. data/test/note_test.rb +158 -0
  47. data/test/object_test.rb +8 -11
  48. data/test/reference_test.rb +77 -85
  49. data/test/remote_test.rb +86 -8
  50. data/test/repo_pack_test.rb +9 -7
  51. data/test/repo_reset_test.rb +80 -0
  52. data/test/repo_test.rb +176 -53
  53. data/test/tag_test.rb +44 -7
  54. data/test/test_helper.rb +63 -35
  55. data/test/tree_test.rb +34 -13
  56. data/test/walker_test.rb +14 -14
  57. data/vendor/libgit2/Makefile.embed +1 -1
  58. data/vendor/libgit2/deps/http-parser/http_parser.c +974 -578
  59. data/vendor/libgit2/deps/http-parser/http_parser.h +106 -70
  60. data/vendor/libgit2/deps/regex/regcomp.c +7 -6
  61. data/vendor/libgit2/deps/regex/regex_internal.c +1 -1
  62. data/vendor/libgit2/deps/regex/regex_internal.h +12 -3
  63. data/vendor/libgit2/deps/regex/regexec.c +5 -5
  64. data/vendor/libgit2/include/git2.h +5 -1
  65. data/vendor/libgit2/include/git2/attr.h +4 -2
  66. data/vendor/libgit2/include/git2/blob.h +39 -12
  67. data/vendor/libgit2/include/git2/branch.h +123 -35
  68. data/vendor/libgit2/include/git2/checkout.h +206 -48
  69. data/vendor/libgit2/include/git2/clone.h +72 -27
  70. data/vendor/libgit2/include/git2/commit.h +20 -17
  71. data/vendor/libgit2/include/git2/common.h +67 -1
  72. data/vendor/libgit2/include/git2/config.h +81 -60
  73. data/vendor/libgit2/include/git2/cred_helpers.h +53 -0
  74. data/vendor/libgit2/include/git2/diff.h +459 -150
  75. data/vendor/libgit2/include/git2/errors.h +9 -1
  76. data/vendor/libgit2/include/git2/graph.h +41 -0
  77. data/vendor/libgit2/include/git2/ignore.h +7 -6
  78. data/vendor/libgit2/include/git2/index.h +323 -97
  79. data/vendor/libgit2/include/git2/indexer.h +27 -59
  80. data/vendor/libgit2/include/git2/inttypes.h +4 -0
  81. data/vendor/libgit2/include/git2/merge.h +13 -3
  82. data/vendor/libgit2/include/git2/message.h +14 -8
  83. data/vendor/libgit2/include/git2/net.h +9 -7
  84. data/vendor/libgit2/include/git2/notes.h +88 -29
  85. data/vendor/libgit2/include/git2/object.h +16 -6
  86. data/vendor/libgit2/include/git2/odb.h +80 -17
  87. data/vendor/libgit2/include/git2/odb_backend.h +47 -11
  88. data/vendor/libgit2/include/git2/oid.h +26 -17
  89. data/vendor/libgit2/include/git2/pack.h +62 -8
  90. data/vendor/libgit2/include/git2/push.h +131 -0
  91. data/vendor/libgit2/include/git2/refdb.h +103 -0
  92. data/vendor/libgit2/include/git2/refdb_backend.h +109 -0
  93. data/vendor/libgit2/include/git2/reflog.h +30 -21
  94. data/vendor/libgit2/include/git2/refs.h +215 -193
  95. data/vendor/libgit2/include/git2/refspec.h +22 -2
  96. data/vendor/libgit2/include/git2/remote.h +158 -37
  97. data/vendor/libgit2/include/git2/repository.h +150 -31
  98. data/vendor/libgit2/include/git2/reset.h +43 -9
  99. data/vendor/libgit2/include/git2/revparse.h +48 -4
  100. data/vendor/libgit2/include/git2/revwalk.h +25 -10
  101. data/vendor/libgit2/include/git2/signature.h +20 -12
  102. data/vendor/libgit2/include/git2/stash.h +121 -0
  103. data/vendor/libgit2/include/git2/status.h +122 -53
  104. data/vendor/libgit2/include/git2/strarray.h +17 -11
  105. data/vendor/libgit2/include/git2/submodule.h +42 -7
  106. data/vendor/libgit2/include/git2/tag.h +72 -59
  107. data/vendor/libgit2/include/git2/threads.h +4 -2
  108. data/vendor/libgit2/include/git2/trace.h +68 -0
  109. data/vendor/libgit2/include/git2/transport.h +328 -0
  110. data/vendor/libgit2/include/git2/tree.h +149 -120
  111. data/vendor/libgit2/include/git2/types.h +13 -12
  112. data/vendor/libgit2/include/git2/version.h +3 -3
  113. data/vendor/libgit2/src/amiga/map.c +2 -2
  114. data/vendor/libgit2/src/attr.c +58 -48
  115. data/vendor/libgit2/src/attr.h +4 -18
  116. data/vendor/libgit2/src/attr_file.c +30 -6
  117. data/vendor/libgit2/src/attr_file.h +6 -8
  118. data/vendor/libgit2/src/attrcache.h +24 -0
  119. data/vendor/libgit2/src/blob.c +30 -7
  120. data/vendor/libgit2/src/blob.h +1 -1
  121. data/vendor/libgit2/src/branch.c +361 -68
  122. data/vendor/libgit2/src/branch.h +17 -0
  123. data/vendor/libgit2/src/bswap.h +1 -1
  124. data/vendor/libgit2/src/buf_text.c +291 -0
  125. data/vendor/libgit2/src/buf_text.h +122 -0
  126. data/vendor/libgit2/src/buffer.c +27 -101
  127. data/vendor/libgit2/src/buffer.h +54 -39
  128. data/vendor/libgit2/src/cache.c +15 -6
  129. data/vendor/libgit2/src/cache.h +1 -1
  130. data/vendor/libgit2/src/cc-compat.h +3 -1
  131. data/vendor/libgit2/src/checkout.c +1165 -222
  132. data/vendor/libgit2/src/checkout.h +24 -0
  133. data/vendor/libgit2/src/clone.c +171 -86
  134. data/vendor/libgit2/src/commit.c +44 -45
  135. data/vendor/libgit2/src/commit.h +3 -3
  136. data/vendor/libgit2/src/commit_list.c +194 -0
  137. data/vendor/libgit2/src/commit_list.h +49 -0
  138. data/vendor/libgit2/src/common.h +44 -10
  139. data/vendor/libgit2/src/compress.c +1 -1
  140. data/vendor/libgit2/src/compress.h +1 -1
  141. data/vendor/libgit2/src/config.c +211 -124
  142. data/vendor/libgit2/src/config.h +23 -4
  143. data/vendor/libgit2/src/config_cache.c +2 -2
  144. data/vendor/libgit2/src/config_file.c +129 -53
  145. data/vendor/libgit2/src/config_file.h +10 -8
  146. data/vendor/libgit2/src/crlf.c +66 -67
  147. data/vendor/libgit2/src/date.c +12 -12
  148. data/vendor/libgit2/src/delta-apply.c +14 -1
  149. data/vendor/libgit2/src/delta-apply.h +18 -1
  150. data/vendor/libgit2/src/delta.c +40 -107
  151. data/vendor/libgit2/src/delta.h +19 -17
  152. data/vendor/libgit2/src/diff.c +347 -496
  153. data/vendor/libgit2/src/diff.h +27 -1
  154. data/vendor/libgit2/src/diff_output.c +564 -249
  155. data/vendor/libgit2/src/diff_output.h +15 -8
  156. data/vendor/libgit2/src/diff_tform.c +687 -0
  157. data/vendor/libgit2/src/errors.c +27 -36
  158. data/vendor/libgit2/src/fetch.c +13 -351
  159. data/vendor/libgit2/src/fetch.h +13 -3
  160. data/vendor/libgit2/src/fetchhead.c +295 -0
  161. data/vendor/libgit2/src/fetchhead.h +34 -0
  162. data/vendor/libgit2/src/filebuf.c +42 -15
  163. data/vendor/libgit2/src/filebuf.h +4 -2
  164. data/vendor/libgit2/src/fileops.c +466 -113
  165. data/vendor/libgit2/src/fileops.h +154 -28
  166. data/vendor/libgit2/src/filter.c +3 -75
  167. data/vendor/libgit2/src/filter.h +1 -29
  168. data/vendor/libgit2/src/fnmatch.c +1 -1
  169. data/vendor/libgit2/src/fnmatch.h +1 -1
  170. data/vendor/libgit2/src/global.c +54 -10
  171. data/vendor/libgit2/src/global.h +10 -1
  172. data/vendor/libgit2/src/graph.c +178 -0
  173. data/vendor/libgit2/src/hash.c +25 -52
  174. data/vendor/libgit2/src/hash.h +21 -9
  175. data/vendor/libgit2/src/{sha1/sha1.c → hash/hash_generic.c} +20 -12
  176. data/vendor/libgit2/src/hash/hash_generic.h +24 -0
  177. data/vendor/libgit2/src/hash/hash_openssl.h +45 -0
  178. data/vendor/libgit2/src/hash/hash_win32.c +291 -0
  179. data/vendor/libgit2/src/hash/hash_win32.h +140 -0
  180. data/vendor/libgit2/src/hashsig.c +368 -0
  181. data/vendor/libgit2/src/hashsig.h +72 -0
  182. data/vendor/libgit2/src/ignore.c +22 -15
  183. data/vendor/libgit2/src/ignore.h +6 -1
  184. data/vendor/libgit2/src/index.c +770 -171
  185. data/vendor/libgit2/src/index.h +13 -5
  186. data/vendor/libgit2/src/indexer.c +286 -431
  187. data/vendor/libgit2/src/iterator.c +854 -466
  188. data/vendor/libgit2/src/iterator.h +134 -109
  189. data/vendor/libgit2/src/map.h +1 -1
  190. data/vendor/libgit2/src/merge.c +296 -0
  191. data/vendor/libgit2/src/merge.h +22 -0
  192. data/vendor/libgit2/src/message.c +1 -1
  193. data/vendor/libgit2/src/message.h +1 -1
  194. data/vendor/libgit2/src/mwindow.c +35 -30
  195. data/vendor/libgit2/src/mwindow.h +2 -2
  196. data/vendor/libgit2/src/netops.c +162 -98
  197. data/vendor/libgit2/src/netops.h +50 -15
  198. data/vendor/libgit2/src/notes.c +109 -58
  199. data/vendor/libgit2/src/notes.h +2 -1
  200. data/vendor/libgit2/src/object.c +46 -57
  201. data/vendor/libgit2/src/object.h +1 -8
  202. data/vendor/libgit2/src/odb.c +151 -40
  203. data/vendor/libgit2/src/odb.h +5 -1
  204. data/vendor/libgit2/src/odb_loose.c +4 -5
  205. data/vendor/libgit2/src/odb_pack.c +122 -80
  206. data/vendor/libgit2/src/offmap.h +65 -0
  207. data/vendor/libgit2/src/oid.c +12 -4
  208. data/vendor/libgit2/src/oidmap.h +1 -1
  209. data/vendor/libgit2/src/pack-objects.c +88 -61
  210. data/vendor/libgit2/src/pack-objects.h +8 -8
  211. data/vendor/libgit2/src/pack.c +293 -28
  212. data/vendor/libgit2/src/pack.h +49 -4
  213. data/vendor/libgit2/src/path.c +103 -14
  214. data/vendor/libgit2/src/path.h +23 -7
  215. data/vendor/libgit2/src/pathspec.c +168 -0
  216. data/vendor/libgit2/src/pathspec.h +40 -0
  217. data/vendor/libgit2/src/pool.c +29 -4
  218. data/vendor/libgit2/src/pool.h +8 -1
  219. data/vendor/libgit2/src/posix.c +26 -27
  220. data/vendor/libgit2/src/posix.h +2 -3
  221. data/vendor/libgit2/src/pqueue.c +23 -1
  222. data/vendor/libgit2/src/pqueue.h +23 -1
  223. data/vendor/libgit2/src/push.c +653 -0
  224. data/vendor/libgit2/src/push.h +51 -0
  225. data/vendor/libgit2/src/refdb.c +185 -0
  226. data/vendor/libgit2/src/refdb.h +46 -0
  227. data/vendor/libgit2/src/refdb_fs.c +1024 -0
  228. data/vendor/libgit2/src/refdb_fs.h +15 -0
  229. data/vendor/libgit2/src/reflog.c +77 -45
  230. data/vendor/libgit2/src/reflog.h +1 -3
  231. data/vendor/libgit2/src/refs.c +366 -1326
  232. data/vendor/libgit2/src/refs.h +22 -13
  233. data/vendor/libgit2/src/refspec.c +46 -7
  234. data/vendor/libgit2/src/refspec.h +11 -1
  235. data/vendor/libgit2/src/remote.c +758 -120
  236. data/vendor/libgit2/src/remote.h +10 -5
  237. data/vendor/libgit2/src/repo_template.h +6 -6
  238. data/vendor/libgit2/src/repository.c +315 -96
  239. data/vendor/libgit2/src/repository.h +5 -3
  240. data/vendor/libgit2/src/reset.c +99 -81
  241. data/vendor/libgit2/src/revparse.c +157 -84
  242. data/vendor/libgit2/src/revwalk.c +68 -470
  243. data/vendor/libgit2/src/revwalk.h +44 -0
  244. data/vendor/libgit2/src/sha1_lookup.c +1 -1
  245. data/vendor/libgit2/src/sha1_lookup.h +1 -1
  246. data/vendor/libgit2/src/signature.c +68 -200
  247. data/vendor/libgit2/src/signature.h +1 -1
  248. data/vendor/libgit2/src/stash.c +663 -0
  249. data/vendor/libgit2/src/status.c +101 -79
  250. data/vendor/libgit2/src/strmap.h +1 -1
  251. data/vendor/libgit2/src/submodule.c +67 -51
  252. data/vendor/libgit2/src/submodule.h +1 -1
  253. data/vendor/libgit2/src/tag.c +35 -29
  254. data/vendor/libgit2/src/tag.h +1 -1
  255. data/vendor/libgit2/src/thread-utils.c +1 -1
  256. data/vendor/libgit2/src/thread-utils.h +2 -2
  257. data/vendor/libgit2/src/trace.c +39 -0
  258. data/vendor/libgit2/src/trace.h +56 -0
  259. data/vendor/libgit2/src/transport.c +81 -34
  260. data/vendor/libgit2/src/transports/cred.c +60 -0
  261. data/vendor/libgit2/src/transports/cred_helpers.c +49 -0
  262. data/vendor/libgit2/src/transports/git.c +234 -127
  263. data/vendor/libgit2/src/transports/http.c +761 -433
  264. data/vendor/libgit2/src/transports/local.c +460 -64
  265. data/vendor/libgit2/src/transports/smart.c +345 -0
  266. data/vendor/libgit2/src/transports/smart.h +179 -0
  267. data/vendor/libgit2/src/{pkt.c → transports/smart_pkt.c} +131 -12
  268. data/vendor/libgit2/src/transports/smart_protocol.c +856 -0
  269. data/vendor/libgit2/src/transports/winhttp.c +1136 -0
  270. data/vendor/libgit2/src/tree-cache.c +2 -2
  271. data/vendor/libgit2/src/tree-cache.h +1 -1
  272. data/vendor/libgit2/src/tree.c +239 -166
  273. data/vendor/libgit2/src/tree.h +11 -2
  274. data/vendor/libgit2/src/tsort.c +39 -23
  275. data/vendor/libgit2/src/unix/map.c +1 -1
  276. data/vendor/libgit2/src/unix/posix.h +12 -2
  277. data/vendor/libgit2/src/unix/realpath.c +30 -0
  278. data/vendor/libgit2/src/util.c +250 -13
  279. data/vendor/libgit2/src/util.h +71 -14
  280. data/vendor/libgit2/src/vector.c +123 -60
  281. data/vendor/libgit2/src/vector.h +24 -22
  282. data/vendor/libgit2/src/win32/dir.c +1 -1
  283. data/vendor/libgit2/src/win32/dir.h +1 -1
  284. data/vendor/libgit2/src/win32/error.c +77 -0
  285. data/vendor/libgit2/src/win32/error.h +13 -0
  286. data/vendor/libgit2/src/win32/findfile.c +143 -54
  287. data/vendor/libgit2/src/win32/findfile.h +10 -6
  288. data/vendor/libgit2/src/win32/map.c +1 -1
  289. data/vendor/libgit2/src/win32/mingw-compat.h +1 -1
  290. data/vendor/libgit2/src/win32/msvc-compat.h +10 -1
  291. data/vendor/libgit2/src/win32/posix.h +10 -1
  292. data/vendor/libgit2/src/win32/posix_w32.c +132 -63
  293. data/vendor/libgit2/src/win32/precompiled.c +1 -1
  294. data/vendor/libgit2/src/win32/pthread.c +1 -1
  295. data/vendor/libgit2/src/win32/pthread.h +1 -1
  296. data/vendor/libgit2/src/win32/utf-conv.c +5 -5
  297. data/vendor/libgit2/src/win32/utf-conv.h +3 -3
  298. data/vendor/libgit2/src/win32/version.h +20 -0
  299. metadata +308 -252
  300. data/test/fixtures/testrepo.git/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904 +0 -0
  301. data/test/fixtures/testrepo.git/objects/7f/043268ea43ce18e3540acaabf9e090c91965b0 +0 -0
  302. data/test/fixtures/testrepo.git/objects/a3/e05719b428a2d0ed7a55c4ce53dcc5768c6d5e +0 -0
  303. data/test/index_test.rb~ +0 -218
  304. data/vendor/libgit2/src/pkt.h +0 -91
  305. data/vendor/libgit2/src/ppc/sha1.c +0 -70
  306. data/vendor/libgit2/src/ppc/sha1.h +0 -26
  307. data/vendor/libgit2/src/protocol.c +0 -110
  308. data/vendor/libgit2/src/protocol.h +0 -21
  309. data/vendor/libgit2/src/sha1.h +0 -33
  310. data/vendor/libgit2/src/transport.h +0 -148
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (C) 2009-2012 the libgit2 contributors
2
+ * Copyright (C) the libgit2 contributors. All rights reserved.
3
3
  *
4
4
  * This file is part of libgit2, distributed under the GNU GPL v2 with
5
5
  * a Linking Exception. For full terms see the included COPYING file.
@@ -19,8 +19,9 @@
19
19
  #include "buffer.h"
20
20
  #include "odb.h"
21
21
  #include "object.h"
22
- #include "attr.h"
22
+ #include "attrcache.h"
23
23
  #include "strmap.h"
24
+ #include "refdb.h"
24
25
 
25
26
  #define DOT_GIT ".git"
26
27
  #define GIT_DIR DOT_GIT "/"
@@ -79,11 +80,11 @@ enum {
79
80
  /** Internal structure for repository object */
80
81
  struct git_repository {
81
82
  git_odb *_odb;
83
+ git_refdb *_refdb;
82
84
  git_config *_config;
83
85
  git_index *_index;
84
86
 
85
87
  git_cache objects;
86
- git_refcache references;
87
88
  git_attr_cache attrcache;
88
89
  git_strmap *submodules;
89
90
 
@@ -112,6 +113,7 @@ int git_repository_head_tree(git_tree **tree, git_repository *repo);
112
113
  */
113
114
  int git_repository_config__weakptr(git_config **out, git_repository *repo);
114
115
  int git_repository_odb__weakptr(git_odb **out, git_repository *repo);
116
+ int git_repository_refdb__weakptr(git_refdb **out, git_repository *repo);
115
117
  int git_repository_index__weakptr(git_index **out, git_repository *repo);
116
118
 
117
119
  /*
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (C) 2009-2012 the libgit2 contributors
2
+ * Copyright (C) the libgit2 contributors. All rights reserved.
3
3
  *
4
4
  * This file is part of libgit2, distributed under the GNU GPL v2 with
5
5
  * a Linking Exception. For full terms see the included COPYING file.
@@ -8,134 +8,152 @@
8
8
  #include "common.h"
9
9
  #include "commit.h"
10
10
  #include "tag.h"
11
+ #include "merge.h"
12
+ #include "diff.h"
11
13
  #include "git2/reset.h"
12
14
  #include "git2/checkout.h"
15
+ #include "git2/merge.h"
16
+ #include "git2/refs.h"
13
17
 
14
18
  #define ERROR_MSG "Cannot perform reset"
15
19
 
16
- static int reset_error_invalid(const char *msg)
17
- {
18
- giterr_set(GITERR_INVALID, "%s - %s", ERROR_MSG, msg);
19
- return -1;
20
- }
21
-
22
- static int update_head(git_repository *repo, git_object *commit)
20
+ int git_reset_default(
21
+ git_repository *repo,
22
+ git_object *target,
23
+ git_strarray* pathspecs)
23
24
  {
25
+ git_object *commit = NULL;
26
+ git_tree *tree = NULL;
27
+ git_diff_list *diff = NULL;
28
+ git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
29
+ size_t i;
30
+ git_diff_delta *delta;
31
+ git_index_entry entry;
24
32
  int error;
25
- git_reference *head = NULL, *target = NULL;
33
+ git_index *index = NULL;
26
34
 
27
- error = git_repository_head(&head, repo);
35
+ assert(pathspecs != NULL && pathspecs->count > 0);
28
36
 
29
- if (error < 0 && error != GIT_EORPHANEDHEAD)
30
- return error;
37
+ memset(&entry, 0, sizeof(git_index_entry));
38
+
39
+ if ((error = git_repository_index(&index, repo)) < 0)
40
+ goto cleanup;
31
41
 
32
- if (error == GIT_EORPHANEDHEAD) {
33
- giterr_clear();
42
+ if (target) {
43
+ if (git_object_owner(target) != repo) {
44
+ giterr_set(GITERR_OBJECT,
45
+ "%s_default - The given target does not belong to this repository.", ERROR_MSG);
46
+ return -1;
47
+ }
34
48
 
35
- /*
36
- * TODO: This is a bit weak as this doesn't support chained
37
- * symbolic references. yet.
38
- */
39
- if ((error = git_reference_lookup(&head, repo, GIT_HEAD_FILE)) < 0)
49
+ if ((error = git_object_peel(&commit, target, GIT_OBJ_COMMIT)) < 0 ||
50
+ (error = git_commit_tree(&tree, (git_commit *)commit)) < 0)
40
51
  goto cleanup;
52
+ }
41
53
 
42
- if ((error = git_reference_create_oid(
43
- &target,
44
- repo,
45
- git_reference_target(head),
46
- git_object_id(commit), 0)) < 0)
47
- goto cleanup;
48
- } else {
49
- if ((error = git_reference_set_oid(head, git_object_id(commit))) < 0)
54
+ opts.pathspec = *pathspecs;
55
+ opts.flags = GIT_DIFF_REVERSE;
56
+
57
+ if ((error = git_diff_tree_to_index(
58
+ &diff, repo, tree, index, &opts)) < 0)
50
59
  goto cleanup;
60
+
61
+ git_vector_foreach(&diff->deltas, i, delta) {
62
+ if ((error = git_index_conflict_remove(index, delta->old_file.path)) < 0)
63
+ goto cleanup;
64
+
65
+ assert(delta->status == GIT_DELTA_ADDED ||
66
+ delta->status == GIT_DELTA_MODIFIED ||
67
+ delta->status == GIT_DELTA_DELETED);
68
+
69
+ if (delta->status == GIT_DELTA_DELETED) {
70
+ if ((error = git_index_remove(index, delta->old_file.path, 0)) < 0)
71
+ goto cleanup;
72
+ } else {
73
+ entry.mode = delta->new_file.mode;
74
+ git_oid_cpy(&entry.oid, &delta->new_file.oid);
75
+ entry.path = (char *)delta->new_file.path;
76
+
77
+ if ((error = git_index_add(index, &entry)) < 0)
78
+ goto cleanup;
79
+ }
51
80
  }
52
81
 
53
- error = 0;
82
+ error = git_index_write(index);
54
83
 
55
84
  cleanup:
56
- git_reference_free(head);
57
- git_reference_free(target);
85
+ git_object_free(commit);
86
+ git_tree_free(tree);
87
+ git_index_free(index);
88
+ git_diff_list_free(diff);
89
+
58
90
  return error;
59
91
  }
60
92
 
61
93
  int git_reset(
62
94
  git_repository *repo,
63
95
  git_object *target,
64
- git_reset_type reset_type)
96
+ git_reset_t reset_type)
65
97
  {
66
98
  git_object *commit = NULL;
67
99
  git_index *index = NULL;
68
100
  git_tree *tree = NULL;
69
- int error = -1;
70
- git_checkout_opts opts;
101
+ int error = 0;
102
+ git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT;
71
103
 
72
104
  assert(repo && target);
73
- assert(reset_type == GIT_RESET_SOFT
74
- || reset_type == GIT_RESET_MIXED
75
- || reset_type == GIT_RESET_HARD);
76
105
 
77
- if (git_object_owner(target) != repo)
78
- return reset_error_invalid("The given target does not belong to this repository.");
79
-
80
- if (reset_type != GIT_RESET_SOFT
81
- && git_repository__ensure_not_bare(
82
- repo,
83
- reset_type == GIT_RESET_MIXED ? "reset mixed" : "reset hard") < 0)
84
- return GIT_EBAREREPO;
85
-
86
- if (git_object_peel(&commit, target, GIT_OBJ_COMMIT) < 0) {
87
- reset_error_invalid("The given target does not resolve to a commit");
88
- goto cleanup;
106
+ if (git_object_owner(target) != repo) {
107
+ giterr_set(GITERR_OBJECT,
108
+ "%s - The given target does not belong to this repository.", ERROR_MSG);
109
+ return -1;
89
110
  }
90
111
 
91
- //TODO: Check for unmerged entries
112
+ if (reset_type != GIT_RESET_SOFT &&
113
+ (error = git_repository__ensure_not_bare(repo,
114
+ reset_type == GIT_RESET_MIXED ? "reset mixed" : "reset hard")) < 0)
115
+ return error;
92
116
 
93
- if (update_head(repo, commit) < 0)
117
+ if ((error = git_object_peel(&commit, target, GIT_OBJ_COMMIT)) < 0 ||
118
+ (error = git_repository_index(&index, repo)) < 0 ||
119
+ (error = git_commit_tree(&tree, (git_commit *)commit)) < 0)
94
120
  goto cleanup;
95
121
 
96
- if (reset_type == GIT_RESET_SOFT) {
97
- error = 0;
122
+ if (reset_type == GIT_RESET_SOFT &&
123
+ (git_repository_state(repo) == GIT_REPOSITORY_STATE_MERGE ||
124
+ git_index_has_conflicts(index)))
125
+ {
126
+ giterr_set(GITERR_OBJECT, "%s (soft) in the middle of a merge.", ERROR_MSG);
127
+ error = GIT_EUNMERGED;
98
128
  goto cleanup;
99
129
  }
100
130
 
101
- if (git_commit_tree(&tree, (git_commit *)commit) < 0) {
102
- giterr_set(GITERR_OBJECT, "%s - Failed to retrieve the commit tree.", ERROR_MSG);
131
+ /* move HEAD to the new target */
132
+ if ((error = git_reference__update_terminal(repo, GIT_HEAD_FILE,
133
+ git_object_id(commit))) < 0)
103
134
  goto cleanup;
104
- }
105
135
 
106
- if (git_repository_index(&index, repo) < 0) {
107
- giterr_set(GITERR_OBJECT, "%s - Failed to retrieve the index.", ERROR_MSG);
108
- goto cleanup;
109
- }
136
+ if (reset_type == GIT_RESET_HARD) {
137
+ /* overwrite working directory with HEAD */
138
+ opts.checkout_strategy = GIT_CHECKOUT_FORCE;
110
139
 
111
- if (git_index_read_tree(index, tree, NULL) < 0) {
112
- giterr_set(GITERR_INDEX, "%s - Failed to update the index.", ERROR_MSG);
113
- goto cleanup;
114
- }
115
-
116
- if (git_index_write(index) < 0) {
117
- giterr_set(GITERR_INDEX, "%s - Failed to write the index.", ERROR_MSG);
118
- goto cleanup;
140
+ if ((error = git_checkout_tree(repo, (git_object *)tree, &opts)) < 0)
141
+ goto cleanup;
119
142
  }
120
143
 
121
- if (reset_type == GIT_RESET_MIXED) {
122
- error = 0;
123
- goto cleanup;
124
- }
144
+ if (reset_type > GIT_RESET_SOFT) {
145
+ /* reset index to the target content */
125
146
 
126
- memset(&opts, 0, sizeof(opts));
127
- opts.checkout_strategy =
128
- GIT_CHECKOUT_CREATE_MISSING
129
- | GIT_CHECKOUT_OVERWRITE_MODIFIED
130
- | GIT_CHECKOUT_REMOVE_UNTRACKED;
147
+ if ((error = git_index_read_tree(index, tree)) < 0 ||
148
+ (error = git_index_write(index)) < 0)
149
+ goto cleanup;
131
150
 
132
- if (git_checkout_index(repo, &opts, NULL) < 0) {
133
- giterr_set(GITERR_INDEX, "%s - Failed to checkout the index.", ERROR_MSG);
134
- goto cleanup;
151
+ if ((error = git_repository_merge_cleanup(repo)) < 0) {
152
+ giterr_set(GITERR_INDEX, "%s - failed to clean up merge data", ERROR_MSG);
153
+ goto cleanup;
154
+ }
135
155
  }
136
156
 
137
- error = 0;
138
-
139
157
  cleanup:
140
158
  git_object_free(commit);
141
159
  git_index_free(index);
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (C) 2009-2012 the libgit2 contributors
2
+ * Copyright (C) the libgit2 contributors. All rights reserved.
3
3
  *
4
4
  * This file is part of libgit2, distributed under the GNU GPL v2 with
5
5
  * a Linking Exception. For full terms see the included COPYING file.
@@ -10,15 +10,10 @@
10
10
  #include "common.h"
11
11
  #include "buffer.h"
12
12
  #include "tree.h"
13
+ #include "refdb.h"
13
14
 
14
15
  #include "git2.h"
15
16
 
16
- static int revspec_error(const char *revspec)
17
- {
18
- giterr_set(GITERR_INVALID, "Failed to parse revision specifier - Invalid pattern '%s'", revspec);
19
- return -1;
20
- }
21
-
22
17
  static int disambiguate_refname(git_reference **out, git_repository *repo, const char *refname)
23
18
  {
24
19
  int error, i;
@@ -51,7 +46,7 @@ static int disambiguate_refname(git_reference **out, git_repository *repo, const
51
46
  goto cleanup;
52
47
 
53
48
  if (!git_reference_is_valid_name(git_buf_cstr(&refnamebuf))) {
54
- error = GIT_ENOTFOUND;
49
+ error = GIT_EINVALIDSPEC;
55
50
  continue;
56
51
  }
57
52
 
@@ -73,10 +68,9 @@ cleanup:
73
68
  return error;
74
69
  }
75
70
 
76
- static int maybe_sha_or_abbrev(git_object**out, git_repository *repo, const char *spec)
71
+ static int maybe_sha_or_abbrev(git_object** out, git_repository *repo, const char *spec, size_t speclen)
77
72
  {
78
73
  git_oid oid;
79
- size_t speclen = strlen(spec);
80
74
 
81
75
  if (git_oid_fromstrn(&oid, spec, speclen) < 0)
82
76
  return GIT_ENOTFOUND;
@@ -84,23 +78,41 @@ static int maybe_sha_or_abbrev(git_object**out, git_repository *repo, const char
84
78
  return git_object_lookup_prefix(out, repo, &oid, speclen, GIT_OBJ_ANY);
85
79
  }
86
80
 
81
+ static int maybe_sha(git_object** out, git_repository *repo, const char *spec)
82
+ {
83
+ size_t speclen = strlen(spec);
84
+
85
+ if (speclen != GIT_OID_HEXSZ)
86
+ return GIT_ENOTFOUND;
87
+
88
+ return maybe_sha_or_abbrev(out, repo, spec, speclen);
89
+ }
90
+
91
+ static int maybe_abbrev(git_object** out, git_repository *repo, const char *spec)
92
+ {
93
+ size_t speclen = strlen(spec);
94
+
95
+ return maybe_sha_or_abbrev(out, repo, spec, speclen);
96
+ }
97
+
87
98
  static int build_regex(regex_t *regex, const char *pattern)
88
99
  {
89
100
  int error;
90
101
 
91
102
  if (*pattern == '\0') {
92
103
  giterr_set(GITERR_REGEX, "Empty pattern");
93
- return -1;
104
+ return GIT_EINVALIDSPEC;
94
105
  }
95
106
 
96
107
  error = regcomp(regex, pattern, REG_EXTENDED);
97
108
  if (!error)
98
109
  return 0;
99
-
100
- giterr_set_regex(regex, error);
110
+
111
+ error = giterr_set_regex(regex, error);
112
+
101
113
  regfree(regex);
102
114
 
103
- return -1;
115
+ return error;
104
116
  }
105
117
 
106
118
  static int maybe_describe(git_object**out, git_repository *repo, const char *spec)
@@ -113,7 +125,7 @@ static int maybe_describe(git_object**out, git_repository *repo, const char *spe
113
125
 
114
126
  if (substr == NULL)
115
127
  return GIT_ENOTFOUND;
116
-
128
+
117
129
  if (build_regex(&regex, ".+-[0-9]+-g[0-9a-fA-F]+") < 0)
118
130
  return -1;
119
131
 
@@ -123,7 +135,7 @@ static int maybe_describe(git_object**out, git_repository *repo, const char *spe
123
135
  if (error)
124
136
  return GIT_ENOTFOUND;
125
137
 
126
- return maybe_sha_or_abbrev(out, repo, substr+2);
138
+ return maybe_abbrev(out, repo, substr+2);
127
139
  }
128
140
 
129
141
  static int revparse_lookup_object(git_object **out, git_repository *repo, const char *spec)
@@ -131,7 +143,7 @@ static int revparse_lookup_object(git_object **out, git_repository *repo, const
131
143
  int error;
132
144
  git_reference *ref;
133
145
 
134
- error = maybe_describe(out, repo, spec);
146
+ error = maybe_sha(out, repo, spec);
135
147
  if (!error)
136
148
  return 0;
137
149
 
@@ -140,7 +152,7 @@ static int revparse_lookup_object(git_object **out, git_repository *repo, const
140
152
 
141
153
  error = disambiguate_refname(&ref, repo, spec);
142
154
  if (!error) {
143
- error = git_object_lookup(out, repo, git_reference_oid(ref), GIT_OBJ_ANY);
155
+ error = git_object_lookup(out, repo, git_reference_target(ref), GIT_OBJ_ANY);
144
156
  git_reference_free(ref);
145
157
  return error;
146
158
  }
@@ -148,7 +160,14 @@ static int revparse_lookup_object(git_object **out, git_repository *repo, const
148
160
  if (error < 0 && error != GIT_ENOTFOUND)
149
161
  return error;
150
162
 
151
- error = maybe_sha_or_abbrev(out, repo, spec);
163
+ error = maybe_abbrev(out, repo, spec);
164
+ if (!error)
165
+ return 0;
166
+
167
+ if (error < 0 && error != GIT_ENOTFOUND)
168
+ return error;
169
+
170
+ error = maybe_describe(out, repo, spec);
152
171
  if (!error)
153
172
  return 0;
154
173
 
@@ -161,7 +180,7 @@ static int revparse_lookup_object(git_object **out, git_repository *repo, const
161
180
 
162
181
  static int try_parse_numeric(int *n, const char *curly_braces_content)
163
182
  {
164
- int content;
183
+ int32_t content;
165
184
  const char *end_ptr;
166
185
 
167
186
  if (git__strtol32(&content, curly_braces_content, &end_ptr, 10) < 0)
@@ -170,16 +189,17 @@ static int try_parse_numeric(int *n, const char *curly_braces_content)
170
189
  if (*end_ptr != '\0')
171
190
  return -1;
172
191
 
173
- *n = content;
192
+ *n = (int)content;
174
193
  return 0;
175
194
  }
176
195
 
177
- static int retrieve_previously_checked_out_branch_or_revision(git_object **out, git_reference **base_ref, git_repository *repo, const char *spec, const char *identifier, unsigned int position)
196
+ static int retrieve_previously_checked_out_branch_or_revision(git_object **out, git_reference **base_ref, git_repository *repo, const char *identifier, size_t position)
178
197
  {
179
198
  git_reference *ref = NULL;
180
199
  git_reflog *reflog = NULL;
181
200
  regex_t preg;
182
- int numentries, i, cur, error = -1;
201
+ int error = -1;
202
+ size_t i, numentries, cur;
183
203
  const git_reflog_entry *entry;
184
204
  const char *msg;
185
205
  regmatch_t regexmatches[2];
@@ -188,7 +208,7 @@ static int retrieve_previously_checked_out_branch_or_revision(git_object **out,
188
208
  cur = position;
189
209
 
190
210
  if (*identifier != '\0' || *base_ref != NULL)
191
- return revspec_error(spec);
211
+ return GIT_EINVALIDSPEC;
192
212
 
193
213
  if (build_regex(&preg, "checkout: moving from (.*) to .*") < 0)
194
214
  return -1;
@@ -201,10 +221,10 @@ static int retrieve_previously_checked_out_branch_or_revision(git_object **out,
201
221
 
202
222
  numentries = git_reflog_entrycount(reflog);
203
223
 
204
- for (i = numentries - 1; i >= 0; i--) {
224
+ for (i = 0; i < numentries; i++) {
205
225
  entry = git_reflog_entry_byindex(reflog, i);
206
- msg = git_reflog_entry_msg(entry);
207
-
226
+ msg = git_reflog_entry_message(entry);
227
+
208
228
  if (regexec(&preg, msg, 2, regexmatches, 0))
209
229
  continue;
210
230
 
@@ -212,7 +232,7 @@ static int retrieve_previously_checked_out_branch_or_revision(git_object **out,
212
232
 
213
233
  if (cur > 0)
214
234
  continue;
215
-
235
+
216
236
  git_buf_put(&buf, msg+regexmatches[1].rm_so, regexmatches[1].rm_eo - regexmatches[1].rm_so);
217
237
 
218
238
  if ((error = disambiguate_refname(base_ref, repo, git_buf_cstr(&buf))) == 0)
@@ -221,11 +241,11 @@ static int retrieve_previously_checked_out_branch_or_revision(git_object **out,
221
241
  if (error < 0 && error != GIT_ENOTFOUND)
222
242
  goto cleanup;
223
243
 
224
- error = maybe_sha_or_abbrev(out, repo, git_buf_cstr(&buf));
244
+ error = maybe_abbrev(out, repo, git_buf_cstr(&buf));
225
245
 
226
246
  goto cleanup;
227
247
  }
228
-
248
+
229
249
  error = GIT_ENOTFOUND;
230
250
 
231
251
  cleanup:
@@ -236,49 +256,47 @@ cleanup:
236
256
  return error;
237
257
  }
238
258
 
239
- static int retrieve_oid_from_reflog(git_oid *oid, git_reference *ref, unsigned int identifier)
259
+ static int retrieve_oid_from_reflog(git_oid *oid, git_reference *ref, size_t identifier)
240
260
  {
241
261
  git_reflog *reflog;
242
262
  int error = -1;
243
- unsigned int numentries;
263
+ size_t numentries;
244
264
  const git_reflog_entry *entry;
245
265
  bool search_by_pos = (identifier <= 100000000);
246
266
 
247
267
  if (git_reflog_read(&reflog, ref) < 0)
248
268
  return -1;
249
269
 
250
- numentries = git_reflog_entrycount(reflog);
270
+ numentries = git_reflog_entrycount(reflog);
251
271
 
252
272
  if (search_by_pos) {
253
273
  if (numentries < identifier + 1) {
254
274
  giterr_set(
255
275
  GITERR_REFERENCE,
256
- "Reflog for '%s' has only %d entries, asked for %d",
257
- git_reference_name(ref),
258
- numentries,
259
- identifier);
276
+ "Reflog for '%s' has only "PRIuZ" entries, asked for "PRIuZ,
277
+ git_reference_name(ref), numentries, identifier);
260
278
 
261
279
  error = GIT_ENOTFOUND;
262
280
  goto cleanup;
263
281
  }
264
282
 
265
283
  entry = git_reflog_entry_byindex(reflog, identifier);
266
- git_oid_cpy(oid, git_reflog_entry_oidold(entry));
284
+ git_oid_cpy(oid, git_reflog_entry_id_new(entry));
267
285
  error = 0;
268
286
  goto cleanup;
269
287
 
270
288
  } else {
271
- int i;
289
+ size_t i;
272
290
  git_time commit_time;
273
291
 
274
- for (i = numentries - 1; i >= 0; i--) {
292
+ for (i = 0; i < numentries; i++) {
275
293
  entry = git_reflog_entry_byindex(reflog, i);
276
294
  commit_time = git_reflog_entry_committer(entry)->when;
277
-
278
- if (commit_time.time - identifier > 0)
295
+
296
+ if (commit_time.time > (git_time_t)identifier)
279
297
  continue;
280
298
 
281
- git_oid_cpy(oid, git_reflog_entry_oidnew(entry));
299
+ git_oid_cpy(oid, git_reflog_entry_id_new(entry));
282
300
  error = 0;
283
301
  goto cleanup;
284
302
  }
@@ -291,7 +309,7 @@ cleanup:
291
309
  return error;
292
310
  }
293
311
 
294
- static int retrieve_revobject_from_reflog(git_object **out, git_reference **base_ref, git_repository *repo, const char *identifier, unsigned int position)
312
+ static int retrieve_revobject_from_reflog(git_object **out, git_reference **base_ref, git_repository *repo, const char *identifier, size_t position)
295
313
  {
296
314
  git_reference *ref;
297
315
  git_oid oid;
@@ -306,7 +324,7 @@ static int retrieve_revobject_from_reflog(git_object **out, git_reference **base
306
324
  }
307
325
 
308
326
  if (position == 0) {
309
- error = git_object_lookup(out, repo, git_reference_oid(ref), GIT_OBJ_ANY);
327
+ error = git_object_lookup(out, repo, git_reference_target(ref), GIT_OBJ_ANY);
310
328
  goto cleanup;
311
329
  }
312
330
 
@@ -333,9 +351,14 @@ static int retrieve_remote_tracking_reference(git_reference **base_ref, const ch
333
351
  *base_ref = NULL;
334
352
  }
335
353
 
336
- if ((error = git_branch_tracking(&tracking, ref)) < 0)
354
+ if (!git_reference_is_branch(ref)) {
355
+ error = GIT_EINVALIDSPEC;
356
+ goto cleanup;
357
+ }
358
+
359
+ if ((error = git_branch_upstream(&tracking, ref)) < 0)
337
360
  goto cleanup;
338
-
361
+
339
362
  *base_ref = tracking;
340
363
 
341
364
  cleanup:
@@ -358,13 +381,13 @@ static int handle_at_syntax(git_object **out, git_reference **ref, const char *s
358
381
  is_numeric = !try_parse_numeric(&parsed, curly_braces_content);
359
382
 
360
383
  if (*curly_braces_content == '-' && (!is_numeric || parsed == 0)) {
361
- error = revspec_error(spec);
384
+ error = GIT_EINVALIDSPEC;
362
385
  goto cleanup;
363
386
  }
364
387
 
365
388
  if (is_numeric) {
366
389
  if (parsed < 0)
367
- error = retrieve_previously_checked_out_branch_or_revision(out, ref, repo, spec, git_buf_cstr(&identifier), -parsed);
390
+ error = retrieve_previously_checked_out_branch_or_revision(out, ref, repo, git_buf_cstr(&identifier), -parsed);
368
391
  else
369
392
  error = retrieve_revobject_from_reflog(out, ref, repo, git_buf_cstr(&identifier), parsed);
370
393
 
@@ -380,7 +403,7 @@ static int handle_at_syntax(git_object **out, git_reference **ref, const char *s
380
403
  if (git__date_parse(&timestamp, curly_braces_content) < 0)
381
404
  goto cleanup;
382
405
 
383
- error = retrieve_revobject_from_reflog(out, ref, repo, git_buf_cstr(&identifier), (unsigned int)timestamp);
406
+ error = retrieve_revobject_from_reflog(out, ref, repo, git_buf_cstr(&identifier), (size_t)timestamp);
384
407
 
385
408
  cleanup:
386
409
  git_buf_free(&identifier);
@@ -394,7 +417,7 @@ static git_otype parse_obj_type(const char *str)
394
417
 
395
418
  if (!strcmp(str, "tree"))
396
419
  return GIT_OBJ_TREE;
397
-
420
+
398
421
  if (!strcmp(str, "blob"))
399
422
  return GIT_OBJ_BLOB;
400
423
 
@@ -409,7 +432,7 @@ static int dereference_to_non_tag(git_object **out, git_object *obj)
409
432
  if (git_object_type(obj) == GIT_OBJ_TAG)
410
433
  return git_tag_peel(out, (git_tag *)obj);
411
434
 
412
- return git_object__dup(out, obj);
435
+ return git_object_dup(out, obj);
413
436
  }
414
437
 
415
438
  static int handle_caret_parent_syntax(git_object **out, git_object *obj, int n)
@@ -417,8 +440,9 @@ static int handle_caret_parent_syntax(git_object **out, git_object *obj, int n)
417
440
  git_object *temp_commit = NULL;
418
441
  int error;
419
442
 
420
- if (git_object_peel(&temp_commit, obj, GIT_OBJ_COMMIT) < 0)
421
- return -1;
443
+ if ((error = git_object_peel(&temp_commit, obj, GIT_OBJ_COMMIT)) < 0)
444
+ return (error == GIT_EAMBIGUOUS || error == GIT_ENOTFOUND) ?
445
+ GIT_EINVALIDSPEC : error;
422
446
 
423
447
  if (n == 0) {
424
448
  *out = temp_commit;
@@ -436,8 +460,9 @@ static int handle_linear_syntax(git_object **out, git_object *obj, int n)
436
460
  git_object *temp_commit = NULL;
437
461
  int error;
438
462
 
439
- if (git_object_peel(&temp_commit, obj, GIT_OBJ_COMMIT) < 0)
440
- return -1;
463
+ if ((error = git_object_peel(&temp_commit, obj, GIT_OBJ_COMMIT)) < 0)
464
+ return (error == GIT_EAMBIGUOUS || error == GIT_ENOTFOUND) ?
465
+ GIT_EINVALIDSPEC : error;
441
466
 
442
467
  error = git_commit_nth_gen_ancestor((git_commit **)out, (git_commit*)temp_commit, n);
443
468
 
@@ -454,8 +479,8 @@ static int handle_colon_syntax(
454
479
  int error = -1;
455
480
  git_tree_entry *entry = NULL;
456
481
 
457
- if (git_object_peel(&tree, obj, GIT_OBJ_TREE) < 0)
458
- return -1;
482
+ if ((error = git_object_peel(&tree, obj, GIT_OBJ_TREE)) < 0)
483
+ return error == GIT_ENOTFOUND ? GIT_EINVALIDSPEC : error;
459
484
 
460
485
  if (*path == '\0') {
461
486
  *out = tree;
@@ -483,11 +508,11 @@ static int walk_and_search(git_object **out, git_revwalk *walk, regex_t *regex)
483
508
  int error;
484
509
  git_oid oid;
485
510
  git_object *obj;
486
-
511
+
487
512
  while (!(error = git_revwalk_next(&oid, walk))) {
488
513
 
489
- if ((error = git_object_lookup(&obj, git_revwalk_repository(walk), &oid, GIT_OBJ_COMMIT) < 0) &&
490
- (error != GIT_ENOTFOUND))
514
+ error = git_object_lookup(&obj, git_revwalk_repository(walk), &oid, GIT_OBJ_COMMIT);
515
+ if ((error < 0) && (error != GIT_ENOTFOUND))
491
516
  return -1;
492
517
 
493
518
  if (!regexec(regex, git_commit_message((git_commit*)obj), 0, NULL, 0)) {
@@ -508,25 +533,25 @@ static int handle_grep_syntax(git_object **out, git_repository *repo, const git_
508
533
  {
509
534
  regex_t preg;
510
535
  git_revwalk *walk = NULL;
511
- int error = -1;
536
+ int error;
512
537
 
513
- if (build_regex(&preg, pattern) < 0)
514
- return -1;
515
-
516
- if (git_revwalk_new(&walk, repo) < 0)
538
+ if ((error = build_regex(&preg, pattern)) < 0)
539
+ return error;
540
+
541
+ if ((error = git_revwalk_new(&walk, repo)) < 0)
517
542
  goto cleanup;
518
543
 
519
544
  git_revwalk_sorting(walk, GIT_SORT_TIME);
520
545
 
521
546
  if (spec_oid == NULL) {
522
547
  // TODO: @carlosmn: The glob should be refs/* but this makes git_revwalk_next() fails
523
- if (git_revwalk_push_glob(walk, GIT_REFS_HEADS_DIR "*") < 0)
548
+ if ((error = git_revwalk_push_glob(walk, GIT_REFS_HEADS_DIR "*")) < 0)
524
549
  goto cleanup;
525
- } else if (git_revwalk_push(walk, spec_oid) < 0)
550
+ } else if ((error = git_revwalk_push(walk, spec_oid)) < 0)
526
551
  goto cleanup;
527
552
 
528
553
  error = walk_and_search(out, walk, &preg);
529
-
554
+
530
555
  cleanup:
531
556
  regfree(&preg);
532
557
  git_revwalk_free(walk);
@@ -547,7 +572,7 @@ static int handle_caret_curly_syntax(git_object **out, git_object *obj, const ch
547
572
  expected_type = parse_obj_type(curly_braces_content);
548
573
 
549
574
  if (expected_type == GIT_OBJ_BAD)
550
- return -1;
575
+ return GIT_EINVALIDSPEC;
551
576
 
552
577
  return git_object_peel(out, obj, expected_type);
553
578
  }
@@ -561,13 +586,13 @@ static int extract_curly_braces_content(git_buf *buf, const char *spec, size_t *
561
586
  (*pos)++;
562
587
 
563
588
  if (spec[*pos] == '\0' || spec[*pos] != '{')
564
- return revspec_error(spec);
589
+ return GIT_EINVALIDSPEC;
565
590
 
566
591
  (*pos)++;
567
592
 
568
593
  while (spec[*pos] != '}') {
569
594
  if (spec[*pos] == '\0')
570
- return revspec_error(spec);
595
+ return GIT_EINVALIDSPEC;
571
596
 
572
597
  git_buf_putc(buf, spec[(*pos)++]);
573
598
  }
@@ -610,8 +635,8 @@ static int extract_how_many(int *n, const char *spec, size_t *pos)
610
635
  } while (spec[(*pos)] == kind && kind == '~');
611
636
 
612
637
  if (git__isdigit(spec[*pos])) {
613
- if ((git__strtol32(&parsed, spec + *pos, &end_ptr, 10) < 0) < 0)
614
- return revspec_error(spec);
638
+ if (git__strtol32(&parsed, spec + *pos, &end_ptr, 10) < 0)
639
+ return GIT_EINVALIDSPEC;
615
640
 
616
641
  accumulated += (parsed - 1);
617
642
  *pos = end_ptr - spec;
@@ -632,7 +657,7 @@ static int object_from_reference(git_object **object, git_reference *reference)
632
657
  if (git_reference_resolve(&resolved, reference) < 0)
633
658
  return -1;
634
659
 
635
- error = git_object_lookup(object, reference->owner, git_reference_oid(resolved), GIT_OBJ_ANY);
660
+ error = git_object_lookup(object, reference->db->repo, git_reference_target(resolved), GIT_OBJ_ANY);
636
661
  git_reference_free(resolved);
637
662
 
638
663
  return error;
@@ -656,7 +681,7 @@ static int ensure_base_rev_loaded(git_object **object, git_reference **reference
656
681
  }
657
682
 
658
683
  if (!allow_empty_identifier && identifier_len == 0)
659
- return revspec_error(spec);
684
+ return GIT_EINVALIDSPEC;
660
685
 
661
686
  if (git_buf_put(&identifier, spec, identifier_len) < 0)
662
687
  return -1;
@@ -667,12 +692,12 @@ static int ensure_base_rev_loaded(git_object **object, git_reference **reference
667
692
  return error;
668
693
  }
669
694
 
670
- static int ensure_base_rev_is_not_known_yet(git_object *object, const char *spec)
695
+ static int ensure_base_rev_is_not_known_yet(git_object *object)
671
696
  {
672
697
  if (object == NULL)
673
698
  return 0;
674
699
 
675
- return revspec_error(spec);
700
+ return GIT_EINVALIDSPEC;
676
701
  }
677
702
 
678
703
  static bool any_left_hand_identifier(git_object *object, git_reference *reference, size_t identifier_len)
@@ -689,12 +714,12 @@ static bool any_left_hand_identifier(git_object *object, git_reference *referenc
689
714
  return false;
690
715
  }
691
716
 
692
- static int ensure_left_hand_identifier_is_not_known_yet(git_object *object, git_reference *reference, const char *spec)
717
+ static int ensure_left_hand_identifier_is_not_known_yet(git_object *object, git_reference *reference)
693
718
  {
694
- if (!ensure_base_rev_is_not_known_yet(object, spec) && reference == NULL)
719
+ if (!ensure_base_rev_is_not_known_yet(object) && reference == NULL)
695
720
  return 0;
696
721
 
697
- return revspec_error(spec);
722
+ return GIT_EINVALIDSPEC;
698
723
  }
699
724
 
700
725
  int git_revparse_single(git_object **out, git_repository *repo, const char *spec)
@@ -801,7 +826,7 @@ int git_revparse_single(git_object **out, git_repository *repo, const char *spec
801
826
  if ((error = extract_curly_braces_content(&buf, spec, &pos)) < 0)
802
827
  goto cleanup;
803
828
 
804
- if ((error = ensure_base_rev_is_not_known_yet(base_rev, spec)) < 0)
829
+ if ((error = ensure_base_rev_is_not_known_yet(base_rev)) < 0)
805
830
  goto cleanup;
806
831
 
807
832
  if ((error = handle_at_syntax(&temp_object, &reference, spec, identifier_len, repo, git_buf_cstr(&buf))) < 0)
@@ -816,7 +841,7 @@ int git_revparse_single(git_object **out, git_repository *repo, const char *spec
816
841
  }
817
842
 
818
843
  default:
819
- if ((error = ensure_left_hand_identifier_is_not_known_yet(base_rev, reference, spec)) < 0)
844
+ if ((error = ensure_left_hand_identifier_is_not_known_yet(base_rev, reference)) < 0)
820
845
  goto cleanup;
821
846
 
822
847
  pos++;
@@ -831,9 +856,57 @@ int git_revparse_single(git_object **out, git_repository *repo, const char *spec
831
856
  error = 0;
832
857
 
833
858
  cleanup:
834
- if (error)
859
+ if (error) {
860
+ if (error == GIT_EINVALIDSPEC)
861
+ giterr_set(GITERR_INVALID,
862
+ "Failed to parse revision specifier - Invalid pattern '%s'", spec);
863
+
835
864
  git_object_free(base_rev);
865
+ }
836
866
  git_reference_free(reference);
837
867
  git_buf_free(&buf);
838
868
  return error;
839
869
  }
870
+
871
+
872
+ int git_revparse(
873
+ git_revspec *revspec,
874
+ git_repository *repo,
875
+ const char *spec)
876
+ {
877
+ const char *dotdot;
878
+ int error = 0;
879
+
880
+ assert(revspec && repo && spec);
881
+
882
+ memset(revspec, 0x0, sizeof(*revspec));
883
+
884
+ if ((dotdot = strstr(spec, "..")) != NULL) {
885
+ char *lstr;
886
+ const char *rstr;
887
+ revspec->flags = GIT_REVPARSE_RANGE;
888
+
889
+ lstr = git__substrdup(spec, dotdot - spec);
890
+ rstr = dotdot + 2;
891
+ if (dotdot[2] == '.') {
892
+ revspec->flags |= GIT_REVPARSE_MERGE_BASE;
893
+ rstr++;
894
+ }
895
+
896
+ if ((error = git_revparse_single(&revspec->from, repo, lstr)) < 0) {
897
+ return error;
898
+ }
899
+
900
+ if ((error = git_revparse_single(&revspec->to, repo, rstr)) < 0) {
901
+ return error;
902
+ }
903
+
904
+ git__free((void*)lstr);
905
+ } else {
906
+ revspec->flags = GIT_REVPARSE_SINGLE;
907
+ error = git_revparse_single(&revspec->from, repo, spec);
908
+ }
909
+
910
+ return error;
911
+ }
912
+