rugged 0.21.4 → 0.22.0b1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (224) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +12 -5
  3. data/ext/rugged/extconf.rb +9 -9
  4. data/ext/rugged/rugged.c +4 -2
  5. data/ext/rugged/rugged.h +3 -7
  6. data/ext/rugged/rugged_blob.c +57 -0
  7. data/ext/rugged/rugged_cred.c +23 -0
  8. data/ext/rugged/rugged_index.c +6 -2
  9. data/ext/rugged/rugged_remote.c +65 -52
  10. data/ext/rugged/rugged_remote_collection.c +59 -10
  11. data/ext/rugged/rugged_repo.c +345 -11
  12. data/ext/rugged/rugged_revwalk.c +10 -0
  13. data/ext/rugged/rugged_submodule.c +1042 -0
  14. data/ext/rugged/rugged_submodule_collection.c +236 -0
  15. data/ext/rugged/rugged_tag_collection.c +70 -2
  16. data/ext/rugged/rugged_tree.c +29 -10
  17. data/lib/rugged.rb +3 -0
  18. data/lib/rugged/attributes.rb +41 -0
  19. data/lib/rugged/blob.rb +28 -0
  20. data/lib/rugged/diff.rb +0 -1
  21. data/lib/rugged/diff/line.rb +1 -3
  22. data/lib/rugged/patch.rb +12 -2
  23. data/lib/rugged/repository.rb +7 -0
  24. data/lib/rugged/submodule_collection.rb +48 -0
  25. data/lib/rugged/version.rb +1 -1
  26. data/vendor/libgit2/CMakeLists.txt +27 -3
  27. data/vendor/libgit2/cmake/Modules/FindGSSAPI.cmake +324 -0
  28. data/vendor/libgit2/deps/http-parser/http_parser.h +2 -0
  29. data/vendor/libgit2/deps/zlib/adler32.c +39 -29
  30. data/vendor/libgit2/deps/zlib/crc32.c +33 -50
  31. data/vendor/libgit2/deps/zlib/crc32.h +1 -1
  32. data/vendor/libgit2/deps/zlib/deflate.c +198 -65
  33. data/vendor/libgit2/deps/zlib/deflate.h +8 -4
  34. data/vendor/libgit2/deps/zlib/infback.c +640 -0
  35. data/vendor/libgit2/deps/zlib/inffast.c +3 -3
  36. data/vendor/libgit2/deps/zlib/inffixed.h +3 -3
  37. data/vendor/libgit2/deps/zlib/inflate.c +84 -52
  38. data/vendor/libgit2/deps/zlib/inftrees.c +15 -39
  39. data/vendor/libgit2/deps/zlib/trees.c +18 -36
  40. data/vendor/libgit2/deps/zlib/zconf.h +4 -0
  41. data/vendor/libgit2/deps/zlib/zlib.h +250 -95
  42. data/vendor/libgit2/deps/zlib/zutil.c +13 -10
  43. data/vendor/libgit2/deps/zlib/zutil.h +41 -62
  44. data/vendor/libgit2/include/git2.h +4 -0
  45. data/vendor/libgit2/include/git2/annotated_commit.h +99 -0
  46. data/vendor/libgit2/include/git2/attr.h +16 -13
  47. data/vendor/libgit2/include/git2/branch.h +11 -0
  48. data/vendor/libgit2/include/git2/buffer.h +16 -0
  49. data/vendor/libgit2/include/git2/checkout.h +12 -12
  50. data/vendor/libgit2/include/git2/cherrypick.h +15 -15
  51. data/vendor/libgit2/include/git2/clone.h +77 -69
  52. data/vendor/libgit2/include/git2/common.h +13 -1
  53. data/vendor/libgit2/include/git2/config.h +0 -14
  54. data/vendor/libgit2/include/git2/describe.h +162 -0
  55. data/vendor/libgit2/include/git2/diff.h +13 -8
  56. data/vendor/libgit2/include/git2/errors.h +5 -0
  57. data/vendor/libgit2/include/git2/global.h +38 -0
  58. data/vendor/libgit2/include/git2/merge.h +38 -64
  59. data/vendor/libgit2/include/git2/net.h +2 -2
  60. data/vendor/libgit2/include/git2/notes.h +17 -0
  61. data/vendor/libgit2/include/git2/oid.h +8 -4
  62. data/vendor/libgit2/include/git2/oidarray.h +40 -0
  63. data/vendor/libgit2/include/git2/rebase.h +261 -0
  64. data/vendor/libgit2/include/git2/reflog.h +1 -1
  65. data/vendor/libgit2/include/git2/remote.h +25 -47
  66. data/vendor/libgit2/include/git2/repository.h +4 -1
  67. data/vendor/libgit2/include/git2/reset.h +10 -1
  68. data/vendor/libgit2/include/git2/revert.h +1 -1
  69. data/vendor/libgit2/include/git2/revwalk.h +28 -23
  70. data/vendor/libgit2/include/git2/status.h +19 -15
  71. data/vendor/libgit2/include/git2/submodule.h +18 -0
  72. data/vendor/libgit2/include/git2/sys/config.h +0 -1
  73. data/vendor/libgit2/{src → include/git2/sys}/hashsig.h +11 -7
  74. data/vendor/libgit2/include/git2/sys/refdb_backend.h +13 -0
  75. data/vendor/libgit2/include/git2/sys/refs.h +0 -11
  76. data/vendor/libgit2/include/git2/sys/repository.h +13 -0
  77. data/vendor/libgit2/include/git2/sys/transport.h +352 -0
  78. data/vendor/libgit2/include/git2/threads.h +10 -20
  79. data/vendor/libgit2/include/git2/transaction.h +111 -0
  80. data/vendor/libgit2/include/git2/transport.h +79 -313
  81. data/vendor/libgit2/include/git2/tree.h +4 -2
  82. data/vendor/libgit2/include/git2/types.h +77 -8
  83. data/vendor/libgit2/include/git2/version.h +2 -2
  84. data/vendor/libgit2/src/annotated_commit.c +121 -0
  85. data/vendor/libgit2/src/annotated_commit.h +22 -0
  86. data/vendor/libgit2/src/attr.c +8 -4
  87. data/vendor/libgit2/src/attr_file.c +24 -2
  88. data/vendor/libgit2/src/blame.c +0 -1
  89. data/vendor/libgit2/src/branch.c +32 -3
  90. data/vendor/libgit2/src/buf_text.c +9 -5
  91. data/vendor/libgit2/src/buf_text.h +3 -2
  92. data/vendor/libgit2/src/buffer.c +67 -10
  93. data/vendor/libgit2/src/buffer.h +4 -2
  94. data/vendor/libgit2/src/cache.c +9 -9
  95. data/vendor/libgit2/src/cache.h +1 -1
  96. data/vendor/libgit2/src/cc-compat.h +2 -0
  97. data/vendor/libgit2/src/checkout.c +263 -82
  98. data/vendor/libgit2/src/checkout.h +1 -0
  99. data/vendor/libgit2/src/cherrypick.c +41 -44
  100. data/vendor/libgit2/src/clone.c +96 -58
  101. data/vendor/libgit2/src/commit.c +5 -31
  102. data/vendor/libgit2/src/commit_list.h +3 -1
  103. data/vendor/libgit2/src/config.c +0 -17
  104. data/vendor/libgit2/src/config_cache.c +0 -2
  105. data/vendor/libgit2/src/config_file.c +12 -15
  106. data/vendor/libgit2/src/crlf.c +2 -1
  107. data/vendor/libgit2/src/describe.c +886 -0
  108. data/vendor/libgit2/src/diff.c +29 -3
  109. data/vendor/libgit2/src/diff_file.c +1 -0
  110. data/vendor/libgit2/src/diff_patch.c +2 -3
  111. data/vendor/libgit2/src/diff_print.c +11 -9
  112. data/vendor/libgit2/src/diff_tform.c +4 -4
  113. data/vendor/libgit2/src/errors.c +9 -7
  114. data/vendor/libgit2/src/fetch.c +6 -6
  115. data/vendor/libgit2/src/fetchhead.h +2 -4
  116. data/vendor/libgit2/src/filebuf.c +0 -2
  117. data/vendor/libgit2/src/filebuf.h +2 -3
  118. data/vendor/libgit2/src/fileops.c +9 -7
  119. data/vendor/libgit2/src/global.c +44 -35
  120. data/vendor/libgit2/src/global.h +2 -0
  121. data/vendor/libgit2/src/graph.c +2 -2
  122. data/vendor/libgit2/src/hash.h +3 -1
  123. data/vendor/libgit2/src/hash/hash_common_crypto.h +44 -0
  124. data/vendor/libgit2/src/hash/hash_win32.c +1 -1
  125. data/vendor/libgit2/src/hashsig.c +1 -1
  126. data/vendor/libgit2/src/ignore.c +5 -88
  127. data/vendor/libgit2/src/index.c +70 -57
  128. data/vendor/libgit2/src/index.h +1 -0
  129. data/vendor/libgit2/src/indexer.c +16 -5
  130. data/vendor/libgit2/src/iterator.c +70 -1
  131. data/vendor/libgit2/src/iterator.h +5 -1
  132. data/vendor/libgit2/src/map.h +0 -1
  133. data/vendor/libgit2/src/merge.c +203 -327
  134. data/vendor/libgit2/src/merge.h +3 -13
  135. data/vendor/libgit2/src/mwindow.c +119 -8
  136. data/vendor/libgit2/src/mwindow.h +9 -1
  137. data/vendor/libgit2/src/netops.c +7 -8
  138. data/vendor/libgit2/src/netops.h +6 -16
  139. data/vendor/libgit2/src/notes.c +31 -4
  140. data/vendor/libgit2/src/notes.h +3 -0
  141. data/vendor/libgit2/src/odb.c +23 -1
  142. data/vendor/libgit2/src/odb_loose.c +1 -1
  143. data/vendor/libgit2/src/odb_pack.c +6 -3
  144. data/vendor/libgit2/src/oid.c +9 -1
  145. data/vendor/libgit2/src/oid.h +11 -0
  146. data/vendor/libgit2/src/oidarray.c +21 -0
  147. data/vendor/libgit2/src/oidarray.h +18 -0
  148. data/vendor/libgit2/src/oidmap.h +16 -0
  149. data/vendor/libgit2/src/pack.c +20 -7
  150. data/vendor/libgit2/src/pack.h +3 -0
  151. data/vendor/libgit2/src/path.c +120 -293
  152. data/vendor/libgit2/src/path.h +21 -44
  153. data/vendor/libgit2/src/pathspec.c +1 -1
  154. data/vendor/libgit2/src/pool.c +5 -11
  155. data/vendor/libgit2/src/pool.h +0 -2
  156. data/vendor/libgit2/src/posix.c +6 -6
  157. data/vendor/libgit2/src/posix.h +48 -28
  158. data/vendor/libgit2/src/push.c +19 -48
  159. data/vendor/libgit2/src/push.h +2 -4
  160. data/vendor/libgit2/src/rebase.c +1125 -0
  161. data/vendor/libgit2/src/refdb.c +19 -0
  162. data/vendor/libgit2/src/refdb.h +2 -1
  163. data/vendor/libgit2/src/refdb_fs.c +101 -29
  164. data/vendor/libgit2/src/reflog.c +1 -1
  165. data/vendor/libgit2/src/refs.c +38 -3
  166. data/vendor/libgit2/src/refs.h +13 -2
  167. data/vendor/libgit2/src/refspec.c +20 -2
  168. data/vendor/libgit2/src/remote.c +288 -154
  169. data/vendor/libgit2/src/remote.h +5 -1
  170. data/vendor/libgit2/src/repository.c +75 -36
  171. data/vendor/libgit2/src/repository.h +3 -25
  172. data/vendor/libgit2/src/reset.c +5 -1
  173. data/vendor/libgit2/src/revert.c +4 -6
  174. data/vendor/libgit2/src/revparse.c +15 -18
  175. data/vendor/libgit2/src/revwalk.c +96 -22
  176. data/vendor/libgit2/src/revwalk.h +5 -4
  177. data/vendor/libgit2/src/settings.c +22 -0
  178. data/vendor/libgit2/src/signature.c +37 -2
  179. data/vendor/libgit2/src/signature.h +3 -0
  180. data/vendor/libgit2/src/stash.c +17 -12
  181. data/vendor/libgit2/src/status.c +13 -3
  182. data/vendor/libgit2/src/strnlen.h +2 -1
  183. data/vendor/libgit2/src/submodule.c +75 -35
  184. data/vendor/libgit2/src/thread-utils.h +4 -9
  185. data/vendor/libgit2/src/trace.h +9 -1
  186. data/vendor/libgit2/src/transaction.c +352 -0
  187. data/vendor/libgit2/src/transport.c +91 -97
  188. data/vendor/libgit2/src/transports/auth.c +71 -0
  189. data/vendor/libgit2/src/transports/auth.h +63 -0
  190. data/vendor/libgit2/src/transports/auth_negotiate.c +275 -0
  191. data/vendor/libgit2/src/transports/auth_negotiate.h +27 -0
  192. data/vendor/libgit2/src/transports/cred.c +58 -0
  193. data/vendor/libgit2/src/transports/cred.h +14 -0
  194. data/vendor/libgit2/src/transports/cred_helpers.c +3 -0
  195. data/vendor/libgit2/src/transports/git.c +1 -0
  196. data/vendor/libgit2/src/transports/http.c +208 -82
  197. data/vendor/libgit2/src/transports/local.c +2 -2
  198. data/vendor/libgit2/src/transports/smart.c +2 -0
  199. data/vendor/libgit2/src/transports/smart.h +2 -0
  200. data/vendor/libgit2/src/transports/smart_protocol.c +10 -10
  201. data/vendor/libgit2/src/transports/ssh.c +243 -57
  202. data/vendor/libgit2/src/transports/winhttp.c +139 -35
  203. data/vendor/libgit2/src/tree-cache.c +118 -31
  204. data/vendor/libgit2/src/tree-cache.h +12 -7
  205. data/vendor/libgit2/src/tree.c +83 -64
  206. data/vendor/libgit2/src/tree.h +2 -3
  207. data/vendor/libgit2/src/unix/map.c +8 -2
  208. data/vendor/libgit2/src/unix/posix.h +23 -9
  209. data/vendor/libgit2/src/unix/realpath.c +8 -7
  210. data/vendor/libgit2/src/userdiff.h +3 -3
  211. data/vendor/libgit2/src/util.c +2 -92
  212. data/vendor/libgit2/src/util.h +3 -15
  213. data/vendor/libgit2/src/win32/findfile.c +0 -1
  214. data/vendor/libgit2/src/win32/map.c +3 -2
  215. data/vendor/libgit2/src/win32/mingw-compat.h +5 -12
  216. data/vendor/libgit2/src/win32/msvc-compat.h +3 -32
  217. data/vendor/libgit2/src/win32/posix.h +20 -32
  218. data/vendor/libgit2/src/win32/posix_w32.c +103 -31
  219. data/vendor/libgit2/src/win32/utf-conv.c +6 -36
  220. data/vendor/libgit2/src/win32/utf-conv.h +39 -0
  221. data/vendor/libgit2/src/win32/w32_util.h +0 -1
  222. metadata +32 -7
  223. data/vendor/libgit2/src/win32/path_w32.c +0 -305
  224. data/vendor/libgit2/src/win32/path_w32.h +0 -82
@@ -65,7 +65,6 @@ static VALUE rb_git_remote_collection_create_anonymous(VALUE self, VALUE rb_url)
65
65
  Data_Get_Struct(rb_repo, git_repository, repo);
66
66
 
67
67
  Check_Type(rb_url, T_STRING);
68
- rugged_validate_remote_url(rb_url);
69
68
 
70
69
  error = git_remote_create_anonymous(
71
70
  &remote,
@@ -102,9 +101,7 @@ static VALUE rb_git_remote_collection_create(VALUE self, VALUE rb_name, VALUE rb
102
101
  Data_Get_Struct(rb_repo, git_repository, repo);
103
102
 
104
103
  Check_Type(rb_name, T_STRING);
105
-
106
104
  Check_Type(rb_url, T_STRING);
107
- rugged_validate_remote_url(rb_url);
108
105
 
109
106
  error = git_remote_create(
110
107
  &remote,
@@ -140,7 +137,7 @@ static VALUE rb_git_remote_collection_aref(VALUE self, VALUE rb_name)
140
137
 
141
138
  Check_Type(rb_name, T_STRING);
142
139
 
143
- error = git_remote_load(&remote, repo, StringValueCStr(rb_name));
140
+ error = git_remote_lookup(&remote, repo, StringValueCStr(rb_name));
144
141
 
145
142
  if (error == GIT_ENOTFOUND)
146
143
  return Qnil;
@@ -182,7 +179,7 @@ static VALUE rb_git_remote_collection__each(VALUE self, int only_names)
182
179
  for (i = 0; !exception && !error && i < remotes.count; ++i) {
183
180
  git_remote *remote;
184
181
 
185
- if (!(error = git_remote_load(&remote, repo, remotes.strings[i])))
182
+ if (!(error = git_remote_lookup(&remote, repo, remotes.strings[i])))
186
183
  rb_protect(rb_yield, rugged_remote_new(rb_repo, remote), &exception);
187
184
  }
188
185
  }
@@ -231,6 +228,61 @@ static VALUE rb_git_remote_collection_each_name(VALUE self)
231
228
  return rb_git_remote_collection__each(self, 1);
232
229
  }
233
230
 
231
+ /*
232
+ * call-seq:
233
+ * remotes.rename(remote, new_name) { |str| } -> remote
234
+ * remotes.rename(name, new_name) { |str| } -> remote
235
+ *
236
+ * Renames a remote.
237
+ *
238
+ * All remote-tracking branches and configuration settings
239
+ * for the remote are updated.
240
+ *
241
+ * Non-default refspecs cannot be renamed automatically and will be
242
+ * yielded to the given block.
243
+ *
244
+ * Anonymous, in-memory remotes created through
245
+ * +ReferenceCollection#create_anonymous+ can not be given a name through
246
+ * this method.
247
+ *
248
+ * Returns a new Rugged::Remote object with the new name.
249
+ */
250
+ static VALUE rb_git_remote_collection_rename(VALUE self, VALUE rb_name_or_remote, VALUE rb_new_name)
251
+ {
252
+ VALUE rb_repo = rugged_owner(self);
253
+ git_repository *repo;
254
+ int i, error, exception;
255
+ git_strarray problems;
256
+
257
+ if (!rb_block_given_p())
258
+ rb_raise(rb_eArgError, "Rugged::RemoteCollection#rename must be called with a block");
259
+
260
+ Check_Type(rb_new_name, T_STRING);
261
+
262
+ if (rb_obj_is_kind_of(rb_name_or_remote, rb_cRuggedRemote))
263
+ rb_name_or_remote = rb_funcall(rb_name_or_remote, rb_intern("name"), 0);
264
+
265
+ if (TYPE(rb_name_or_remote) != T_STRING)
266
+ rb_raise(rb_eTypeError, "Expecting a String or Rugged::Remote instance");
267
+
268
+ rugged_check_repo(rb_repo);
269
+ Data_Get_Struct(rb_repo, git_repository, repo);
270
+
271
+ error = git_remote_rename(&problems, repo, StringValueCStr(rb_name_or_remote), StringValueCStr(rb_new_name));
272
+ rugged_exception_check(error);
273
+
274
+ for (i = exception = 0; !exception && i < problems.count; ++i) {
275
+ rb_protect(rb_yield, rb_str_new_utf8(problems.strings[i]), &exception);
276
+ }
277
+
278
+ git_strarray_free(&problems);
279
+
280
+ if (exception)
281
+ rb_jump_tag(exception);
282
+
283
+ return rb_git_remote_collection_aref(self, rb_new_name);
284
+ }
285
+
234
286
  /*
235
287
  * call-seq:
236
288
  * remotes.delete(remote) -> nil
@@ -244,7 +296,6 @@ static VALUE rb_git_remote_collection_each_name(VALUE self)
244
296
  static VALUE rb_git_remote_collection_delete(VALUE self, VALUE rb_name_or_remote)
245
297
  {
246
298
  VALUE rb_repo = rugged_owner(self);
247
- git_remote *remote;
248
299
  git_repository *repo;
249
300
  int error;
250
301
 
@@ -257,10 +308,7 @@ static VALUE rb_git_remote_collection_delete(VALUE self, VALUE rb_name_or_remote
257
308
  rugged_check_repo(rb_repo);
258
309
  Data_Get_Struct(rb_repo, git_repository, repo);
259
310
 
260
- error = git_remote_load(&remote, repo, StringValueCStr(rb_name_or_remote));
261
- rugged_exception_check(error);
262
-
263
- error = git_remote_delete(remote);
311
+ error = git_remote_delete(repo, StringValueCStr(rb_name_or_remote));
264
312
  rugged_exception_check(error);
265
313
 
266
314
  return Qnil;
@@ -281,5 +329,6 @@ void Init_rugged_remote_collection(void)
281
329
  rb_define_method(rb_cRuggedRemoteCollection, "each", rb_git_remote_collection_each, 0);
282
330
  rb_define_method(rb_cRuggedRemoteCollection, "each_name", rb_git_remote_collection_each_name, 0);
283
331
 
332
+ rb_define_method(rb_cRuggedRemoteCollection, "rename", rb_git_remote_collection_rename, 2);
284
333
  rb_define_method(rb_cRuggedRemoteCollection, "delete", rb_git_remote_collection_delete, 1);
285
334
  }
@@ -138,7 +138,7 @@ void rb_git_repo__free(git_repository *repo)
138
138
  git_repository_free(repo);
139
139
  }
140
140
 
141
- static VALUE rugged_repo_new(VALUE klass, git_repository *repo)
141
+ VALUE rugged_repo_new(VALUE klass, git_repository *repo)
142
142
  {
143
143
  VALUE rb_repo = Data_Wrap_Struct(klass, NULL, &rb_git_repo__free, repo);
144
144
 
@@ -515,6 +515,56 @@ static VALUE rb_git_repo_merge_base(VALUE self, VALUE rb_args)
515
515
  return rugged_create_oid(&base);
516
516
  }
517
517
 
518
+ /*
519
+ * call-seq:
520
+ * repo.merge_bases(oid1, oid2, ...) -> Array
521
+ * repo.merge_bases(ref1, ref2, ...) -> Array
522
+ * repo.merge_bases(commit1, commit2, ...) -> Array
523
+ *
524
+ * Find all merge bases, given two or more commits or oids.
525
+ * Returns an empty array if no merge bases are found.
526
+ */
527
+ static VALUE rb_git_repo_merge_bases(VALUE self, VALUE rb_args)
528
+ {
529
+ int error = GIT_OK, i;
530
+ git_repository *repo;
531
+ git_oidarray bases = {NULL, 0};
532
+ git_oid *input_array = xmalloc(sizeof(git_oid) * RARRAY_LEN(rb_args));
533
+ int len = (int)RARRAY_LEN(rb_args);
534
+
535
+ VALUE rb_bases;
536
+
537
+ if (len < 2)
538
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for 2+)", len);
539
+
540
+ Data_Get_Struct(self, git_repository, repo);
541
+
542
+ for (i = 0; !error && i < len; ++i) {
543
+ error = rugged_oid_get(&input_array[i], repo, rb_ary_entry(rb_args, i));
544
+ }
545
+
546
+ if (error) {
547
+ xfree(input_array);
548
+ rugged_exception_check(error);
549
+ }
550
+
551
+ error = git_merge_bases_many(&bases, repo, len, input_array);
552
+ xfree(input_array);
553
+
554
+ if (error != GIT_ENOTFOUND)
555
+ rugged_exception_check(error);
556
+
557
+ rb_bases = rb_ary_new2(bases.count);
558
+
559
+ for (i = 0; i < bases.count; ++i) {
560
+ rb_ary_push(rb_bases, rugged_create_oid(&bases.ids[i]));
561
+ }
562
+
563
+ git_oidarray_free(&bases);
564
+
565
+ return rb_bases;
566
+ }
567
+
518
568
  /*
519
569
  * call-seq:
520
570
  * repo.merge_analysis(their_commit) -> Array
@@ -546,7 +596,7 @@ static VALUE rb_git_repo_merge_analysis(int argc, VALUE *argv, VALUE self)
546
596
  int error;
547
597
  git_repository *repo;
548
598
  git_commit *their_commit;
549
- git_merge_head *merge_head;
599
+ git_annotated_commit *annotated_commit;
550
600
  git_merge_analysis_t analysis;
551
601
  git_merge_preference_t preference;
552
602
  VALUE rb_their_commit, result;
@@ -565,13 +615,13 @@ static VALUE rb_git_repo_merge_analysis(int argc, VALUE *argv, VALUE self)
565
615
 
566
616
  Data_Get_Struct(rb_their_commit, git_commit, their_commit);
567
617
 
568
- error = git_merge_head_from_id(&merge_head, repo, git_commit_id(their_commit));
618
+ error = git_annotated_commit_lookup(&annotated_commit, repo, git_commit_id(their_commit));
569
619
  rugged_exception_check(error);
570
620
 
571
621
  error = git_merge_analysis(&analysis, &preference, repo,
572
622
  /* hack as we currently only do one commit */
573
- (const git_merge_head **) &merge_head, 1);
574
- git_merge_head_free(merge_head);
623
+ (const git_annotated_commit **) &annotated_commit, 1);
624
+ git_annotated_commit_free(annotated_commit);
575
625
  rugged_exception_check(error);
576
626
 
577
627
  result = rb_ary_new();
@@ -643,9 +693,10 @@ static VALUE rb_git_repo_merge_commits(int argc, VALUE *argv, VALUE self)
643
693
  * repo.exists?(oid) -> true or false
644
694
  *
645
695
  * Return whether an object with the given SHA1 OID (represented as
646
- * a 40-character string) exists in the repository.
696
+ * a hex string of at least 7 characters) exists in the repository.
647
697
  *
648
698
  * repo.include?("d8786bfc97485e8d7b19b21fb88c8ef1f199fc3f") #=> true
699
+ * repo.include?("d8786bfc") #=> true
649
700
  */
650
701
  static VALUE rb_git_repo_exists(VALUE self, VALUE hex)
651
702
  {
@@ -653,21 +704,23 @@ static VALUE rb_git_repo_exists(VALUE self, VALUE hex)
653
704
  git_odb *odb;
654
705
  git_oid oid;
655
706
  int error;
656
- VALUE rb_result;
657
707
 
658
708
  Data_Get_Struct(self, git_repository, repo);
659
709
  Check_Type(hex, T_STRING);
660
710
 
661
- error = git_oid_fromstr(&oid, StringValueCStr(hex));
711
+ error = git_oid_fromstrn(&oid, RSTRING_PTR(hex), RSTRING_LEN(hex));
662
712
  rugged_exception_check(error);
663
713
 
664
714
  error = git_repository_odb(&odb, repo);
665
715
  rugged_exception_check(error);
666
716
 
667
- rb_result = git_odb_exists(odb, &oid) ? Qtrue : Qfalse;
717
+ error = git_odb_exists_prefix(NULL, odb, &oid, RSTRING_LEN(hex));
668
718
  git_odb_free(odb);
669
719
 
670
- return rb_result;
720
+ if (error == 0 || error == GIT_EAMBIGUOUS)
721
+ return Qtrue;
722
+
723
+ return Qfalse;
671
724
  }
672
725
 
673
726
  /*
@@ -736,6 +789,107 @@ static VALUE rb_git_repo_read_header(VALUE self, VALUE hex)
736
789
  return rb_hash;
737
790
  }
738
791
 
792
+ /**
793
+ * call-seq:
794
+ * repo.expand_oids([oid..], object_type = :any) -> hash
795
+ *
796
+ * Expand a list of short oids to their full value, assuming they exist
797
+ * in the repository. If `object_type` is passed, OIDs are expected to be
798
+ * of the given type.
799
+ *
800
+ * Returns a hash of `{ short_oid => full_oid }` for the short OIDs which
801
+ * exist in the repository and match the expected object type. Missing OIDs
802
+ * will not appear in the resulting hash.
803
+ */
804
+ static VALUE rb_git_repo_expand_oids(int argc, VALUE *argv, VALUE self)
805
+ {
806
+ VALUE rb_result, rb_oids, rb_expected_type;
807
+
808
+ git_otype expected_type = GIT_OBJ_ANY;
809
+
810
+ git_repository *repo;
811
+ git_oid oid;
812
+ git_odb *odb;
813
+ int i, error;
814
+
815
+ Data_Get_Struct(self, git_repository, repo);
816
+
817
+ rb_scan_args(argc, argv, "11", &rb_oids, &rb_expected_type);
818
+
819
+ Check_Type(rb_oids, T_ARRAY);
820
+ expected_type = rugged_otype_get(rb_expected_type);
821
+
822
+ error = git_repository_odb(&odb, repo);
823
+ rugged_exception_check(error);
824
+
825
+ rb_result = rb_hash_new();
826
+
827
+ for (i = 0; i < RARRAY_LEN(rb_oids); ++i) {
828
+ VALUE hex_oid = rb_ary_entry(rb_oids, i);
829
+ git_oid found_oid;
830
+
831
+ if (TYPE(hex_oid) != T_STRING) {
832
+ git_odb_free(odb);
833
+ rb_raise(rb_eTypeError, "Expected a SHA1 OID");
834
+ }
835
+
836
+ error = git_oid_fromstrn(&oid, RSTRING_PTR(hex_oid), RSTRING_LEN(hex_oid));
837
+ if (error < 0) {
838
+ git_odb_free(odb);
839
+ rugged_exception_check(error);
840
+ }
841
+
842
+ error = git_odb_exists_prefix(&found_oid, odb, &oid, RSTRING_LEN(hex_oid));
843
+
844
+ if (!error) {
845
+ if (expected_type != GIT_OBJ_ANY) {
846
+ size_t found_size;
847
+ git_otype found_type;
848
+
849
+ if (git_odb_read_header(&found_size, &found_type, odb, &found_oid) < 0)
850
+ continue;
851
+
852
+ if (found_type != expected_type)
853
+ continue;
854
+ }
855
+
856
+ rb_hash_aset(rb_result, hex_oid, rugged_create_oid(&found_oid));
857
+ }
858
+ }
859
+
860
+ git_odb_free(odb);
861
+ return rb_result;
862
+ }
863
+
864
+ /*
865
+ * call-seq:
866
+ * repo.descendant_of?(commit, ancestor) -> true or false
867
+ *
868
+ * +commit+ and +ancestor+ must be String commit OIDs or instances of Rugged::Commit.
869
+ *
870
+ * Returns true if +commit+ is a descendant of +ancestor+, or false if not.
871
+ */
872
+ static VALUE rb_git_repo_descendant_of(VALUE self, VALUE rb_commit, VALUE rb_ancestor)
873
+ {
874
+ int result;
875
+ int error;
876
+ git_repository *repo;
877
+ git_oid commit, ancestor;
878
+
879
+ Data_Get_Struct(self, git_repository, repo);
880
+
881
+ error = rugged_oid_get(&commit, repo, rb_commit);
882
+ rugged_exception_check(error);
883
+
884
+ error = rugged_oid_get(&ancestor, repo, rb_ancestor);
885
+ rugged_exception_check(error);
886
+
887
+ result = git_graph_descendant_of(repo, &commit, &ancestor);
888
+ rugged_exception_check(result);
889
+
890
+ return result ? Qtrue : Qfalse;
891
+ }
892
+
739
893
  /*
740
894
  * call-seq:
741
895
  * Repository.hash_data(str, type) -> oid
@@ -1296,7 +1450,7 @@ static VALUE rb_git_repo_reset(int argc, VALUE *argv, VALUE self)
1296
1450
  log_message = StringValueCStr(rb_val);
1297
1451
  }
1298
1452
 
1299
- error = git_reset(repo, target, reset_type, signature, log_message);
1453
+ error = git_reset(repo, target, reset_type, NULL, signature, log_message);
1300
1454
 
1301
1455
  git_object_free(target);
1302
1456
  git_signature_free(signature);
@@ -1924,6 +2078,179 @@ static VALUE rb_git_repo_is_path_ignored(VALUE self, VALUE rb_path) {
1924
2078
  return ignored ? Qtrue : Qfalse;
1925
2079
  }
1926
2080
 
2081
+ static void rugged_parse_cherrypick_options(git_cherrypick_options *opts, VALUE rb_options)
2082
+ {
2083
+ VALUE rb_value;
2084
+
2085
+ if (NIL_P(rb_options))
2086
+ return;
2087
+
2088
+ Check_Type(rb_options, T_HASH);
2089
+
2090
+ rb_value = rb_hash_aref(rb_options, CSTR2SYM("mainline"));
2091
+ if (!NIL_P(rb_value)) {
2092
+ opts->mainline = FIX2UINT(rb_value);
2093
+ }
2094
+ }
2095
+
2096
+ static VALUE rugged_create_attr(const char *attr)
2097
+ {
2098
+ switch (git_attr_value(attr)) {
2099
+ case GIT_ATTR_TRUE_T:
2100
+ return Qtrue;
2101
+
2102
+ case GIT_ATTR_FALSE_T:
2103
+ return Qfalse;
2104
+
2105
+ case GIT_ATTR_VALUE_T:
2106
+ return rb_str_new2(attr);
2107
+
2108
+ case GIT_ATTR_UNSPECIFIED_T:
2109
+ default:
2110
+ return Qnil;
2111
+ }
2112
+ }
2113
+
2114
+ static int foreach_attr_hash(const char *name, const char *value, void *payload)
2115
+ {
2116
+ VALUE rb_hash = (VALUE)payload;
2117
+ rb_hash_aset(rb_hash, rb_str_new2(name), rugged_create_attr(value));
2118
+ return 0;
2119
+ }
2120
+
2121
+ static VALUE rb_git_repo_attributes(int argc, VALUE *argv, VALUE self)
2122
+ {
2123
+ VALUE rb_path, rb_names, rb_options;
2124
+
2125
+ git_repository *repo;
2126
+ int error, options = 0;
2127
+
2128
+ rb_scan_args(argc, argv, "12", &rb_path, &rb_names, &rb_options);
2129
+
2130
+ Data_Get_Struct(self, git_repository, repo);
2131
+ Check_Type(rb_path, T_STRING);
2132
+
2133
+ if (!NIL_P(rb_options)) {
2134
+ Check_Type(rb_options, T_FIXNUM);
2135
+ options = FIX2INT(rb_options);
2136
+ }
2137
+
2138
+ switch (TYPE(rb_names)) {
2139
+ case T_ARRAY:
2140
+ {
2141
+ VALUE rb_result;
2142
+ const char **values;
2143
+ const char **names;
2144
+ int i, num_attr = RARRAY_LEN(rb_names);
2145
+
2146
+ if (num_attr > 32)
2147
+ rb_raise(rb_eRuntimeError, "Too many attributes requested");
2148
+
2149
+ values = alloca(num_attr * sizeof(const char *));
2150
+ names = alloca(num_attr * sizeof(const char *));
2151
+
2152
+ for (i = 0; i < num_attr; ++i) {
2153
+ VALUE attr = rb_ary_entry(rb_names, i);
2154
+ Check_Type(attr, T_STRING);
2155
+ names[i] = StringValueCStr(attr);
2156
+ }
2157
+
2158
+ error = git_attr_get_many(
2159
+ values, repo, options,
2160
+ StringValueCStr(rb_path),
2161
+ (size_t)num_attr, names);
2162
+
2163
+ rugged_exception_check(error);
2164
+
2165
+ rb_result = rb_hash_new();
2166
+ for (i = 0; i < num_attr; ++i) {
2167
+ VALUE attr = rb_ary_entry(rb_names, i);
2168
+ rb_hash_aset(rb_result, attr, rugged_create_attr(values[i]));
2169
+ }
2170
+ return rb_result;
2171
+ }
2172
+
2173
+ case T_STRING:
2174
+ {
2175
+ const char *value;
2176
+
2177
+ error = git_attr_get(
2178
+ &value, repo, options,
2179
+ StringValueCStr(rb_path),
2180
+ StringValueCStr(rb_names));
2181
+
2182
+ rugged_exception_check(error);
2183
+
2184
+ return rugged_create_attr(value);
2185
+ }
2186
+
2187
+ case T_NIL:
2188
+ {
2189
+ VALUE rb_result = rb_hash_new();
2190
+
2191
+ error = git_attr_foreach(
2192
+ repo, options,
2193
+ StringValueCStr(rb_path),
2194
+ &foreach_attr_hash,
2195
+ (void *)rb_result);
2196
+
2197
+ rugged_exception_check(error);
2198
+ return rb_result;
2199
+ }
2200
+
2201
+ default:
2202
+ rb_raise(rb_eTypeError,
2203
+ "Invalid attribute name (expected String or Array)");
2204
+ }
2205
+ }
2206
+
2207
+ /*
2208
+ * call-seq:
2209
+ * repo.cherrypick(commit[, options]) -> nil
2210
+ *
2211
+ * Cherry-pick the given commit and update the index and working
2212
+ * directory accordingly.
2213
+ *
2214
+ * `commit` can be either a string containing a commit id or a
2215
+ * `Rugged::Commit` object.
2216
+ *
2217
+ * The following options can be passed in the +options+ Hash:
2218
+ *
2219
+ * :mainline ::
2220
+ * When cherry-picking a merge, you need to specify the parent number
2221
+ * (starting from 1) which should be considered the mainline.
2222
+ */
2223
+ static VALUE rb_git_repo_cherrypick(int argc, VALUE *argv, VALUE self)
2224
+ {
2225
+ VALUE rb_options, rb_commit;
2226
+
2227
+ git_repository *repo;
2228
+ git_commit *commit;
2229
+ git_cherrypick_options opts = GIT_CHERRYPICK_OPTIONS_INIT;
2230
+
2231
+ int error;
2232
+
2233
+ rb_scan_args(argc, argv, "10:", &rb_commit, &rb_options);
2234
+
2235
+ if (TYPE(rb_commit) == T_STRING) {
2236
+ rb_commit = rugged_object_rev_parse(self, rb_commit, 1);
2237
+ }
2238
+
2239
+ if (!rb_obj_is_kind_of(rb_commit, rb_cRuggedCommit)) {
2240
+ rb_raise(rb_eArgError, "Expected a Rugged::Commit.");
2241
+ }
2242
+
2243
+ Data_Get_Struct(self, git_repository, repo);
2244
+ Data_Get_Struct(rb_commit, git_commit, commit);
2245
+
2246
+ rugged_parse_cherrypick_options(&opts, rb_options);
2247
+
2248
+ error = git_cherrypick(repo, commit, &opts);
2249
+ rugged_exception_check(error);
2250
+
2251
+ return Qnil;
2252
+ }
2253
+
1927
2254
  void Init_rugged_repo(void)
1928
2255
  {
1929
2256
  id_call = rb_intern("call");
@@ -1942,6 +2269,8 @@ void Init_rugged_repo(void)
1942
2269
 
1943
2270
  rb_define_method(rb_cRuggedRepo, "exists?", rb_git_repo_exists, 1);
1944
2271
  rb_define_method(rb_cRuggedRepo, "include?", rb_git_repo_exists, 1);
2272
+ rb_define_method(rb_cRuggedRepo, "expand_oids", rb_git_repo_expand_oids, -1);
2273
+ rb_define_method(rb_cRuggedRepo, "descendant_of?", rb_git_repo_descendant_of, 2);
1945
2274
 
1946
2275
  rb_define_method(rb_cRuggedRepo, "read", rb_git_repo_read, 1);
1947
2276
  rb_define_method(rb_cRuggedRepo, "read_header", rb_git_repo_read_header, 1);
@@ -1968,6 +2297,8 @@ void Init_rugged_repo(void)
1968
2297
  rb_define_method(rb_cRuggedRepo, "head", rb_git_repo_get_head, 0);
1969
2298
 
1970
2299
  rb_define_method(rb_cRuggedRepo, "merge_base", rb_git_repo_merge_base, -2);
2300
+ rb_define_method(rb_cRuggedRepo, "merge_bases", rb_git_repo_merge_bases, -2);
2301
+
1971
2302
  rb_define_method(rb_cRuggedRepo, "merge_analysis", rb_git_repo_merge_analysis, -1);
1972
2303
  rb_define_method(rb_cRuggedRepo, "merge_commits", rb_git_repo_merge_commits, -1);
1973
2304
 
@@ -1986,6 +2317,9 @@ void Init_rugged_repo(void)
1986
2317
  rb_define_method(rb_cRuggedRepo, "checkout_tree", rb_git_checkout_tree, -1);
1987
2318
  rb_define_method(rb_cRuggedRepo, "checkout_head", rb_git_checkout_head, -1);
1988
2319
 
2320
+ rb_define_method(rb_cRuggedRepo, "cherrypick", rb_git_repo_cherrypick, -1);
2321
+ rb_define_method(rb_cRuggedRepo, "fetch_attributes", rb_git_repo_attributes, -1);
2322
+
1989
2323
  rb_cRuggedOdbObject = rb_define_class_under(rb_mRugged, "OdbObject", rb_cObject);
1990
2324
  rb_define_method(rb_cRuggedOdbObject, "data", rb_git_odbobj_data, 0);
1991
2325
  rb_define_method(rb_cRuggedOdbObject, "len", rb_git_odbobj_size, 0);