rugged 0.17.0.b7 → 0.18.0.b1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (310) hide show
  1. data/LICENSE +1 -1
  2. data/README.md +88 -32
  3. data/ext/rugged/extconf.rb +4 -2
  4. data/ext/rugged/rugged.c +72 -10
  5. data/ext/rugged/rugged.h +14 -10
  6. data/ext/rugged/rugged_blob.c +8 -10
  7. data/ext/rugged/rugged_branch.c +11 -14
  8. data/ext/rugged/rugged_commit.c +31 -24
  9. data/ext/rugged/rugged_config.c +2 -2
  10. data/ext/rugged/rugged_index.c +133 -198
  11. data/ext/rugged/rugged_note.c +372 -0
  12. data/ext/rugged/rugged_object.c +50 -22
  13. data/ext/rugged/rugged_reference.c +122 -130
  14. data/ext/rugged/rugged_remote.c +72 -29
  15. data/ext/rugged/rugged_repo.c +402 -20
  16. data/ext/rugged/rugged_revwalk.c +7 -3
  17. data/ext/rugged/rugged_settings.c +110 -0
  18. data/ext/rugged/rugged_signature.c +23 -7
  19. data/ext/rugged/rugged_tag.c +32 -16
  20. data/ext/rugged/rugged_tree.c +44 -15
  21. data/lib/rugged.rb +1 -0
  22. data/lib/rugged/index.rb +8 -0
  23. data/lib/rugged/remote.rb +13 -0
  24. data/lib/rugged/repository.rb +3 -3
  25. data/lib/rugged/version.rb +1 -1
  26. data/test/blob_test.rb +13 -15
  27. data/test/branch_test.rb +32 -67
  28. data/test/commit_test.rb +50 -12
  29. data/test/config_test.rb +12 -11
  30. data/test/coverage/HEAD.json +1 -1
  31. data/test/coverage/cover.rb +40 -21
  32. data/test/errors_test.rb +34 -0
  33. data/test/fixtures/alternate/objects/14/6ae76773c91e3b1d00cf7a338ec55ae58297e2 +0 -0
  34. data/test/fixtures/alternate/objects/14/9c32d47e99d0a3572ff1e70a2e0051bbf347a9 +0 -0
  35. data/test/fixtures/alternate/objects/14/fb3108588f9421bf764041e5e3ac305eb6277f +0 -0
  36. data/test/fixtures/testrepo.git/logs/refs/notes/commits +1 -0
  37. data/test/fixtures/testrepo.git/objects/44/1034f860c1d5d90e4188d11ae0d325176869a8 +1 -0
  38. data/test/fixtures/testrepo.git/objects/60/d415052a33de2150bf68757f6461df4f563ae4 +0 -0
  39. data/test/fixtures/testrepo.git/objects/68/8a8f4ef7496901d15322972f96e212a9e466cc +1 -0
  40. data/test/fixtures/testrepo.git/objects/94/eca2de348d5f672faf56b0decafa5937e3235e +0 -0
  41. data/test/fixtures/testrepo.git/objects/9b/7384fe1676186192842f5d3e129457b62db9e3 +0 -0
  42. data/test/fixtures/testrepo.git/objects/b7/4713326bc972cc15751ed504dca6f6f3b91f7a +3 -0
  43. data/test/fixtures/testrepo.git/refs/notes/commits +1 -0
  44. data/test/index_test.rb +65 -69
  45. data/test/lib_test.rb +76 -11
  46. data/test/note_test.rb +158 -0
  47. data/test/object_test.rb +8 -11
  48. data/test/reference_test.rb +77 -85
  49. data/test/remote_test.rb +86 -8
  50. data/test/repo_pack_test.rb +9 -7
  51. data/test/repo_reset_test.rb +80 -0
  52. data/test/repo_test.rb +176 -53
  53. data/test/tag_test.rb +44 -7
  54. data/test/test_helper.rb +63 -35
  55. data/test/tree_test.rb +34 -13
  56. data/test/walker_test.rb +14 -14
  57. data/vendor/libgit2/Makefile.embed +1 -1
  58. data/vendor/libgit2/deps/http-parser/http_parser.c +974 -578
  59. data/vendor/libgit2/deps/http-parser/http_parser.h +106 -70
  60. data/vendor/libgit2/deps/regex/regcomp.c +7 -6
  61. data/vendor/libgit2/deps/regex/regex_internal.c +1 -1
  62. data/vendor/libgit2/deps/regex/regex_internal.h +12 -3
  63. data/vendor/libgit2/deps/regex/regexec.c +5 -5
  64. data/vendor/libgit2/include/git2.h +5 -1
  65. data/vendor/libgit2/include/git2/attr.h +4 -2
  66. data/vendor/libgit2/include/git2/blob.h +39 -12
  67. data/vendor/libgit2/include/git2/branch.h +123 -35
  68. data/vendor/libgit2/include/git2/checkout.h +206 -48
  69. data/vendor/libgit2/include/git2/clone.h +72 -27
  70. data/vendor/libgit2/include/git2/commit.h +20 -17
  71. data/vendor/libgit2/include/git2/common.h +67 -1
  72. data/vendor/libgit2/include/git2/config.h +81 -60
  73. data/vendor/libgit2/include/git2/cred_helpers.h +53 -0
  74. data/vendor/libgit2/include/git2/diff.h +459 -150
  75. data/vendor/libgit2/include/git2/errors.h +9 -1
  76. data/vendor/libgit2/include/git2/graph.h +41 -0
  77. data/vendor/libgit2/include/git2/ignore.h +7 -6
  78. data/vendor/libgit2/include/git2/index.h +323 -97
  79. data/vendor/libgit2/include/git2/indexer.h +27 -59
  80. data/vendor/libgit2/include/git2/inttypes.h +4 -0
  81. data/vendor/libgit2/include/git2/merge.h +13 -3
  82. data/vendor/libgit2/include/git2/message.h +14 -8
  83. data/vendor/libgit2/include/git2/net.h +9 -7
  84. data/vendor/libgit2/include/git2/notes.h +88 -29
  85. data/vendor/libgit2/include/git2/object.h +16 -6
  86. data/vendor/libgit2/include/git2/odb.h +80 -17
  87. data/vendor/libgit2/include/git2/odb_backend.h +47 -11
  88. data/vendor/libgit2/include/git2/oid.h +26 -17
  89. data/vendor/libgit2/include/git2/pack.h +62 -8
  90. data/vendor/libgit2/include/git2/push.h +131 -0
  91. data/vendor/libgit2/include/git2/refdb.h +103 -0
  92. data/vendor/libgit2/include/git2/refdb_backend.h +109 -0
  93. data/vendor/libgit2/include/git2/reflog.h +30 -21
  94. data/vendor/libgit2/include/git2/refs.h +215 -193
  95. data/vendor/libgit2/include/git2/refspec.h +22 -2
  96. data/vendor/libgit2/include/git2/remote.h +158 -37
  97. data/vendor/libgit2/include/git2/repository.h +150 -31
  98. data/vendor/libgit2/include/git2/reset.h +43 -9
  99. data/vendor/libgit2/include/git2/revparse.h +48 -4
  100. data/vendor/libgit2/include/git2/revwalk.h +25 -10
  101. data/vendor/libgit2/include/git2/signature.h +20 -12
  102. data/vendor/libgit2/include/git2/stash.h +121 -0
  103. data/vendor/libgit2/include/git2/status.h +122 -53
  104. data/vendor/libgit2/include/git2/strarray.h +17 -11
  105. data/vendor/libgit2/include/git2/submodule.h +42 -7
  106. data/vendor/libgit2/include/git2/tag.h +72 -59
  107. data/vendor/libgit2/include/git2/threads.h +4 -2
  108. data/vendor/libgit2/include/git2/trace.h +68 -0
  109. data/vendor/libgit2/include/git2/transport.h +328 -0
  110. data/vendor/libgit2/include/git2/tree.h +149 -120
  111. data/vendor/libgit2/include/git2/types.h +13 -12
  112. data/vendor/libgit2/include/git2/version.h +3 -3
  113. data/vendor/libgit2/src/amiga/map.c +2 -2
  114. data/vendor/libgit2/src/attr.c +58 -48
  115. data/vendor/libgit2/src/attr.h +4 -18
  116. data/vendor/libgit2/src/attr_file.c +30 -6
  117. data/vendor/libgit2/src/attr_file.h +6 -8
  118. data/vendor/libgit2/src/attrcache.h +24 -0
  119. data/vendor/libgit2/src/blob.c +30 -7
  120. data/vendor/libgit2/src/blob.h +1 -1
  121. data/vendor/libgit2/src/branch.c +361 -68
  122. data/vendor/libgit2/src/branch.h +17 -0
  123. data/vendor/libgit2/src/bswap.h +1 -1
  124. data/vendor/libgit2/src/buf_text.c +291 -0
  125. data/vendor/libgit2/src/buf_text.h +122 -0
  126. data/vendor/libgit2/src/buffer.c +27 -101
  127. data/vendor/libgit2/src/buffer.h +54 -39
  128. data/vendor/libgit2/src/cache.c +15 -6
  129. data/vendor/libgit2/src/cache.h +1 -1
  130. data/vendor/libgit2/src/cc-compat.h +3 -1
  131. data/vendor/libgit2/src/checkout.c +1165 -222
  132. data/vendor/libgit2/src/checkout.h +24 -0
  133. data/vendor/libgit2/src/clone.c +171 -86
  134. data/vendor/libgit2/src/commit.c +44 -45
  135. data/vendor/libgit2/src/commit.h +3 -3
  136. data/vendor/libgit2/src/commit_list.c +194 -0
  137. data/vendor/libgit2/src/commit_list.h +49 -0
  138. data/vendor/libgit2/src/common.h +44 -10
  139. data/vendor/libgit2/src/compress.c +1 -1
  140. data/vendor/libgit2/src/compress.h +1 -1
  141. data/vendor/libgit2/src/config.c +211 -124
  142. data/vendor/libgit2/src/config.h +23 -4
  143. data/vendor/libgit2/src/config_cache.c +2 -2
  144. data/vendor/libgit2/src/config_file.c +129 -53
  145. data/vendor/libgit2/src/config_file.h +10 -8
  146. data/vendor/libgit2/src/crlf.c +66 -67
  147. data/vendor/libgit2/src/date.c +12 -12
  148. data/vendor/libgit2/src/delta-apply.c +14 -1
  149. data/vendor/libgit2/src/delta-apply.h +18 -1
  150. data/vendor/libgit2/src/delta.c +40 -107
  151. data/vendor/libgit2/src/delta.h +19 -17
  152. data/vendor/libgit2/src/diff.c +347 -496
  153. data/vendor/libgit2/src/diff.h +27 -1
  154. data/vendor/libgit2/src/diff_output.c +564 -249
  155. data/vendor/libgit2/src/diff_output.h +15 -8
  156. data/vendor/libgit2/src/diff_tform.c +687 -0
  157. data/vendor/libgit2/src/errors.c +27 -36
  158. data/vendor/libgit2/src/fetch.c +13 -351
  159. data/vendor/libgit2/src/fetch.h +13 -3
  160. data/vendor/libgit2/src/fetchhead.c +295 -0
  161. data/vendor/libgit2/src/fetchhead.h +34 -0
  162. data/vendor/libgit2/src/filebuf.c +42 -15
  163. data/vendor/libgit2/src/filebuf.h +4 -2
  164. data/vendor/libgit2/src/fileops.c +466 -113
  165. data/vendor/libgit2/src/fileops.h +154 -28
  166. data/vendor/libgit2/src/filter.c +3 -75
  167. data/vendor/libgit2/src/filter.h +1 -29
  168. data/vendor/libgit2/src/fnmatch.c +1 -1
  169. data/vendor/libgit2/src/fnmatch.h +1 -1
  170. data/vendor/libgit2/src/global.c +54 -10
  171. data/vendor/libgit2/src/global.h +10 -1
  172. data/vendor/libgit2/src/graph.c +178 -0
  173. data/vendor/libgit2/src/hash.c +25 -52
  174. data/vendor/libgit2/src/hash.h +21 -9
  175. data/vendor/libgit2/src/{sha1/sha1.c → hash/hash_generic.c} +20 -12
  176. data/vendor/libgit2/src/hash/hash_generic.h +24 -0
  177. data/vendor/libgit2/src/hash/hash_openssl.h +45 -0
  178. data/vendor/libgit2/src/hash/hash_win32.c +291 -0
  179. data/vendor/libgit2/src/hash/hash_win32.h +140 -0
  180. data/vendor/libgit2/src/hashsig.c +368 -0
  181. data/vendor/libgit2/src/hashsig.h +72 -0
  182. data/vendor/libgit2/src/ignore.c +22 -15
  183. data/vendor/libgit2/src/ignore.h +6 -1
  184. data/vendor/libgit2/src/index.c +770 -171
  185. data/vendor/libgit2/src/index.h +13 -5
  186. data/vendor/libgit2/src/indexer.c +286 -431
  187. data/vendor/libgit2/src/iterator.c +854 -466
  188. data/vendor/libgit2/src/iterator.h +134 -109
  189. data/vendor/libgit2/src/map.h +1 -1
  190. data/vendor/libgit2/src/merge.c +296 -0
  191. data/vendor/libgit2/src/merge.h +22 -0
  192. data/vendor/libgit2/src/message.c +1 -1
  193. data/vendor/libgit2/src/message.h +1 -1
  194. data/vendor/libgit2/src/mwindow.c +35 -30
  195. data/vendor/libgit2/src/mwindow.h +2 -2
  196. data/vendor/libgit2/src/netops.c +162 -98
  197. data/vendor/libgit2/src/netops.h +50 -15
  198. data/vendor/libgit2/src/notes.c +109 -58
  199. data/vendor/libgit2/src/notes.h +2 -1
  200. data/vendor/libgit2/src/object.c +46 -57
  201. data/vendor/libgit2/src/object.h +1 -8
  202. data/vendor/libgit2/src/odb.c +151 -40
  203. data/vendor/libgit2/src/odb.h +5 -1
  204. data/vendor/libgit2/src/odb_loose.c +4 -5
  205. data/vendor/libgit2/src/odb_pack.c +122 -80
  206. data/vendor/libgit2/src/offmap.h +65 -0
  207. data/vendor/libgit2/src/oid.c +12 -4
  208. data/vendor/libgit2/src/oidmap.h +1 -1
  209. data/vendor/libgit2/src/pack-objects.c +88 -61
  210. data/vendor/libgit2/src/pack-objects.h +8 -8
  211. data/vendor/libgit2/src/pack.c +293 -28
  212. data/vendor/libgit2/src/pack.h +49 -4
  213. data/vendor/libgit2/src/path.c +103 -14
  214. data/vendor/libgit2/src/path.h +23 -7
  215. data/vendor/libgit2/src/pathspec.c +168 -0
  216. data/vendor/libgit2/src/pathspec.h +40 -0
  217. data/vendor/libgit2/src/pool.c +29 -4
  218. data/vendor/libgit2/src/pool.h +8 -1
  219. data/vendor/libgit2/src/posix.c +26 -27
  220. data/vendor/libgit2/src/posix.h +2 -3
  221. data/vendor/libgit2/src/pqueue.c +23 -1
  222. data/vendor/libgit2/src/pqueue.h +23 -1
  223. data/vendor/libgit2/src/push.c +653 -0
  224. data/vendor/libgit2/src/push.h +51 -0
  225. data/vendor/libgit2/src/refdb.c +185 -0
  226. data/vendor/libgit2/src/refdb.h +46 -0
  227. data/vendor/libgit2/src/refdb_fs.c +1024 -0
  228. data/vendor/libgit2/src/refdb_fs.h +15 -0
  229. data/vendor/libgit2/src/reflog.c +77 -45
  230. data/vendor/libgit2/src/reflog.h +1 -3
  231. data/vendor/libgit2/src/refs.c +366 -1326
  232. data/vendor/libgit2/src/refs.h +22 -13
  233. data/vendor/libgit2/src/refspec.c +46 -7
  234. data/vendor/libgit2/src/refspec.h +11 -1
  235. data/vendor/libgit2/src/remote.c +758 -120
  236. data/vendor/libgit2/src/remote.h +10 -5
  237. data/vendor/libgit2/src/repo_template.h +6 -6
  238. data/vendor/libgit2/src/repository.c +315 -96
  239. data/vendor/libgit2/src/repository.h +5 -3
  240. data/vendor/libgit2/src/reset.c +99 -81
  241. data/vendor/libgit2/src/revparse.c +157 -84
  242. data/vendor/libgit2/src/revwalk.c +68 -470
  243. data/vendor/libgit2/src/revwalk.h +44 -0
  244. data/vendor/libgit2/src/sha1_lookup.c +1 -1
  245. data/vendor/libgit2/src/sha1_lookup.h +1 -1
  246. data/vendor/libgit2/src/signature.c +68 -200
  247. data/vendor/libgit2/src/signature.h +1 -1
  248. data/vendor/libgit2/src/stash.c +663 -0
  249. data/vendor/libgit2/src/status.c +101 -79
  250. data/vendor/libgit2/src/strmap.h +1 -1
  251. data/vendor/libgit2/src/submodule.c +67 -51
  252. data/vendor/libgit2/src/submodule.h +1 -1
  253. data/vendor/libgit2/src/tag.c +35 -29
  254. data/vendor/libgit2/src/tag.h +1 -1
  255. data/vendor/libgit2/src/thread-utils.c +1 -1
  256. data/vendor/libgit2/src/thread-utils.h +2 -2
  257. data/vendor/libgit2/src/trace.c +39 -0
  258. data/vendor/libgit2/src/trace.h +56 -0
  259. data/vendor/libgit2/src/transport.c +81 -34
  260. data/vendor/libgit2/src/transports/cred.c +60 -0
  261. data/vendor/libgit2/src/transports/cred_helpers.c +49 -0
  262. data/vendor/libgit2/src/transports/git.c +234 -127
  263. data/vendor/libgit2/src/transports/http.c +761 -433
  264. data/vendor/libgit2/src/transports/local.c +460 -64
  265. data/vendor/libgit2/src/transports/smart.c +345 -0
  266. data/vendor/libgit2/src/transports/smart.h +179 -0
  267. data/vendor/libgit2/src/{pkt.c → transports/smart_pkt.c} +131 -12
  268. data/vendor/libgit2/src/transports/smart_protocol.c +856 -0
  269. data/vendor/libgit2/src/transports/winhttp.c +1136 -0
  270. data/vendor/libgit2/src/tree-cache.c +2 -2
  271. data/vendor/libgit2/src/tree-cache.h +1 -1
  272. data/vendor/libgit2/src/tree.c +239 -166
  273. data/vendor/libgit2/src/tree.h +11 -2
  274. data/vendor/libgit2/src/tsort.c +39 -23
  275. data/vendor/libgit2/src/unix/map.c +1 -1
  276. data/vendor/libgit2/src/unix/posix.h +12 -2
  277. data/vendor/libgit2/src/unix/realpath.c +30 -0
  278. data/vendor/libgit2/src/util.c +250 -13
  279. data/vendor/libgit2/src/util.h +71 -14
  280. data/vendor/libgit2/src/vector.c +123 -60
  281. data/vendor/libgit2/src/vector.h +24 -22
  282. data/vendor/libgit2/src/win32/dir.c +1 -1
  283. data/vendor/libgit2/src/win32/dir.h +1 -1
  284. data/vendor/libgit2/src/win32/error.c +77 -0
  285. data/vendor/libgit2/src/win32/error.h +13 -0
  286. data/vendor/libgit2/src/win32/findfile.c +143 -54
  287. data/vendor/libgit2/src/win32/findfile.h +10 -6
  288. data/vendor/libgit2/src/win32/map.c +1 -1
  289. data/vendor/libgit2/src/win32/mingw-compat.h +1 -1
  290. data/vendor/libgit2/src/win32/msvc-compat.h +10 -1
  291. data/vendor/libgit2/src/win32/posix.h +10 -1
  292. data/vendor/libgit2/src/win32/posix_w32.c +132 -63
  293. data/vendor/libgit2/src/win32/precompiled.c +1 -1
  294. data/vendor/libgit2/src/win32/pthread.c +1 -1
  295. data/vendor/libgit2/src/win32/pthread.h +1 -1
  296. data/vendor/libgit2/src/win32/utf-conv.c +5 -5
  297. data/vendor/libgit2/src/win32/utf-conv.h +3 -3
  298. data/vendor/libgit2/src/win32/version.h +20 -0
  299. metadata +308 -252
  300. data/test/fixtures/testrepo.git/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904 +0 -0
  301. data/test/fixtures/testrepo.git/objects/7f/043268ea43ce18e3540acaabf9e090c91965b0 +0 -0
  302. data/test/fixtures/testrepo.git/objects/a3/e05719b428a2d0ed7a55c4ce53dcc5768c6d5e +0 -0
  303. data/test/index_test.rb~ +0 -218
  304. data/vendor/libgit2/src/pkt.h +0 -91
  305. data/vendor/libgit2/src/ppc/sha1.c +0 -70
  306. data/vendor/libgit2/src/ppc/sha1.h +0 -26
  307. data/vendor/libgit2/src/protocol.c +0 -110
  308. data/vendor/libgit2/src/protocol.h +0 -21
  309. data/vendor/libgit2/src/sha1.h +0 -33
  310. data/vendor/libgit2/src/transport.h +0 -148
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (C) 2009-2012 the libgit2 contributors
2
+ * Copyright (C) the libgit2 contributors. All rights reserved.
3
3
  *
4
4
  * This file is part of libgit2, distributed under the GNU GPL v2 with
5
5
  * a Linking Exception. For full terms see the included COPYING file.
@@ -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
+