rugged 0.18.0.gh.de28323 → 0.19.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (283) hide show
  1. data/README.md +9 -4
  2. data/Rakefile +1 -1
  3. data/ext/rugged/extconf.rb +10 -0
  4. data/ext/rugged/rugged.c +153 -86
  5. data/ext/rugged/rugged.h +44 -33
  6. data/ext/rugged/rugged_blob.c +288 -60
  7. data/ext/rugged/rugged_branch.c +82 -57
  8. data/ext/rugged/rugged_commit.c +83 -86
  9. data/ext/rugged/rugged_config.c +68 -68
  10. data/ext/rugged/rugged_diff.c +509 -0
  11. data/ext/rugged/rugged_diff_delta.c +94 -0
  12. data/ext/rugged/rugged_diff_hunk.c +100 -0
  13. data/ext/rugged/rugged_diff_line.c +79 -0
  14. data/ext/rugged/rugged_diff_patch.c +169 -0
  15. data/ext/rugged/rugged_index.c +539 -8
  16. data/ext/rugged/rugged_note.c +74 -80
  17. data/ext/rugged/rugged_object.c +63 -8
  18. data/ext/rugged/rugged_reference.c +231 -145
  19. data/ext/rugged/rugged_remote.c +509 -53
  20. data/ext/rugged/rugged_repo.c +572 -236
  21. data/ext/rugged/rugged_revwalk.c +59 -36
  22. data/ext/rugged/rugged_settings.c +7 -9
  23. data/ext/rugged/rugged_signature.c +7 -11
  24. data/ext/rugged/rugged_tag.c +93 -39
  25. data/ext/rugged/rugged_tree.c +321 -58
  26. data/lib/rugged.rb +1 -0
  27. data/lib/rugged/commit.rb +16 -1
  28. data/lib/rugged/console.rb +9 -0
  29. data/lib/rugged/diff.rb +19 -0
  30. data/lib/rugged/diff/delta.rb +54 -0
  31. data/lib/rugged/diff/hunk.rb +23 -0
  32. data/lib/rugged/diff/line.rb +29 -0
  33. data/lib/rugged/diff/patch.rb +28 -0
  34. data/lib/rugged/repository.rb +36 -39
  35. data/lib/rugged/version.rb +1 -1
  36. data/test/blob_test.rb +308 -1
  37. data/test/branch_test.rb +7 -0
  38. data/test/commit_test.rb +7 -10
  39. data/test/coverage/cover.rb +9 -1
  40. data/test/diff_test.rb +777 -0
  41. data/test/fixtures/archive.tar.gz +0 -0
  42. data/test/fixtures/attr/attr0 +1 -0
  43. data/test/fixtures/attr/attr1 +29 -0
  44. data/test/fixtures/attr/attr2 +21 -0
  45. data/test/fixtures/attr/attr3 +4 -0
  46. data/test/fixtures/attr/binfile +1 -0
  47. data/test/fixtures/attr/dir/file +0 -0
  48. data/test/fixtures/attr/file +1 -0
  49. data/test/fixtures/attr/gitattributes +29 -0
  50. data/test/fixtures/attr/gitignore +2 -0
  51. data/test/fixtures/attr/ign +1 -0
  52. data/test/fixtures/attr/macro_bad +1 -0
  53. data/test/fixtures/attr/macro_test +1 -0
  54. data/test/fixtures/attr/root_test1 +1 -0
  55. data/test/fixtures/attr/root_test2 +6 -0
  56. data/test/fixtures/attr/root_test3 +19 -0
  57. data/test/fixtures/attr/root_test4.txt +14 -0
  58. data/test/fixtures/attr/sub/abc +37 -0
  59. data/test/fixtures/attr/sub/dir/file +0 -0
  60. data/test/fixtures/attr/sub/file +1 -0
  61. data/test/fixtures/attr/sub/ign/file +1 -0
  62. data/test/fixtures/attr/sub/ign/sub/file +1 -0
  63. data/test/fixtures/attr/sub/sub/dir +0 -0
  64. data/test/fixtures/attr/sub/sub/file +1 -0
  65. data/test/fixtures/attr/sub/sub/subsub.txt +1 -0
  66. data/test/fixtures/attr/sub/subdir_test1 +2 -0
  67. data/test/fixtures/attr/sub/subdir_test2.txt +1 -0
  68. data/test/fixtures/diff/another.txt +38 -0
  69. data/test/fixtures/diff/readme.txt +36 -0
  70. data/test/fixtures/mergedrepo/conflicts-one.txt +5 -0
  71. data/test/fixtures/mergedrepo/conflicts-two.txt +5 -0
  72. data/test/fixtures/mergedrepo/one.txt +10 -0
  73. data/test/fixtures/mergedrepo/two.txt +12 -0
  74. data/test/fixtures/status/current_file +1 -0
  75. data/test/fixtures/status/ignored_file +1 -0
  76. data/test/fixtures/status/modified_file +2 -0
  77. data/test/fixtures/status/new_file +1 -0
  78. data/test/fixtures/status/staged_changes +2 -0
  79. data/test/fixtures/status/staged_changes_modified_file +3 -0
  80. data/test/fixtures/status/staged_delete_modified_file +1 -0
  81. data/test/fixtures/status/staged_new_file +1 -0
  82. data/test/fixtures/status/staged_new_file_modified_file +2 -0
  83. data/test/fixtures/status/subdir.txt +2 -0
  84. data/test/fixtures/status/subdir/current_file +1 -0
  85. data/test/fixtures/status/subdir/modified_file +2 -0
  86. data/test/fixtures/status/subdir/new_file +1 -0
  87. data/test/fixtures/status//350/277/231 +1 -0
  88. data/test/fixtures/testrepo.git/config +5 -0
  89. data/test/fixtures/testrepo.git/objects/77/71329dfa3002caf8c61a0ceb62a31d09023f37 +0 -0
  90. data/test/fixtures/text_file.md +464 -0
  91. data/test/fixtures/unsymlinked.git/HEAD +1 -0
  92. data/test/fixtures/unsymlinked.git/config +6 -0
  93. data/test/fixtures/unsymlinked.git/description +1 -0
  94. data/test/fixtures/unsymlinked.git/info/exclude +2 -0
  95. data/test/fixtures/unsymlinked.git/objects/08/8b64704e0d6b8bd061dea879418cb5442a3fbf +0 -0
  96. data/test/fixtures/unsymlinked.git/objects/13/a5e939bca25940c069fd2169d993dba328e30b +0 -0
  97. data/test/fixtures/unsymlinked.git/objects/19/bf568e59e3a0b363cafb4106226e62d4a4c41c +0 -0
  98. data/test/fixtures/unsymlinked.git/objects/58/1fadd35b4cf320d102a152f918729011604773 +0 -0
  99. data/test/fixtures/unsymlinked.git/objects/5c/87b6791e8b13da658a14d1ef7e09b5dc3bac8c +0 -0
  100. data/test/fixtures/unsymlinked.git/objects/6f/e5f5398af85fb3de8a6aba0339b6d3bfa26a27 +0 -0
  101. data/test/fixtures/unsymlinked.git/objects/7f/ccd75616ec188b8f1b23d67506a334cc34a49d +0 -0
  102. data/test/fixtures/unsymlinked.git/objects/80/6999882bf91d24241e4077906b9017605eb1f3 +0 -0
  103. data/test/fixtures/unsymlinked.git/objects/83/7d176303c5005505ec1e4a30231c40930c0230 +0 -0
  104. data/test/fixtures/unsymlinked.git/objects/a8/595ccca04f40818ae0155c8f9c77a230e597b6 +2 -0
  105. data/test/fixtures/unsymlinked.git/objects/cf/8f1cf5cce859c438d6cc067284cb5e161206e7 +0 -0
  106. data/test/fixtures/unsymlinked.git/objects/d5/278d05c8607ec420bfee4cf219fbc0eeebfd6a +0 -0
  107. data/test/fixtures/unsymlinked.git/objects/f4/e16fb76536591a41454194058d048d8e4dd2e9 +0 -0
  108. data/test/fixtures/unsymlinked.git/objects/f9/e65619d93fdf2673882e0a261c5e93b1a84006 +0 -0
  109. data/test/fixtures/unsymlinked.git/refs/heads/exe-file +1 -0
  110. data/test/fixtures/unsymlinked.git/refs/heads/master +1 -0
  111. data/test/fixtures/unsymlinked.git/refs/heads/reg-file +1 -0
  112. data/test/index_test.rb +120 -0
  113. data/test/reference_test.rb +38 -3
  114. data/test/remote_test.rb +224 -3
  115. data/test/repo_reset_test.rb +2 -0
  116. data/test/repo_test.rb +147 -10
  117. data/test/test_helper.rb +5 -2
  118. data/vendor/libgit2/include/git2/attr.h +3 -3
  119. data/vendor/libgit2/include/git2/blob.h +11 -17
  120. data/vendor/libgit2/include/git2/branch.h +3 -2
  121. data/vendor/libgit2/include/git2/checkout.h +7 -0
  122. data/vendor/libgit2/include/git2/clone.h +3 -0
  123. data/vendor/libgit2/include/git2/commit.h +61 -66
  124. data/vendor/libgit2/include/git2/common.h +73 -42
  125. data/vendor/libgit2/include/git2/config.h +57 -71
  126. data/vendor/libgit2/include/git2/cred_helpers.h +2 -2
  127. data/vendor/libgit2/include/git2/diff.h +179 -30
  128. data/vendor/libgit2/include/git2/errors.h +3 -3
  129. data/vendor/libgit2/include/git2/index.h +225 -146
  130. data/vendor/libgit2/include/git2/indexer.h +2 -22
  131. data/vendor/libgit2/include/git2/inttypes.h +9 -9
  132. data/vendor/libgit2/include/git2/merge.h +123 -5
  133. data/vendor/libgit2/include/git2/odb.h +59 -38
  134. data/vendor/libgit2/include/git2/odb_backend.h +45 -104
  135. data/vendor/libgit2/include/git2/oid.h +30 -19
  136. data/vendor/libgit2/include/git2/pack.h +21 -3
  137. data/vendor/libgit2/include/git2/refdb.h +0 -35
  138. data/vendor/libgit2/include/git2/refs.h +93 -31
  139. data/vendor/libgit2/include/git2/refspec.h +17 -0
  140. data/vendor/libgit2/include/git2/remote.h +60 -20
  141. data/vendor/libgit2/include/git2/repository.h +48 -70
  142. data/vendor/libgit2/include/git2/reset.h +3 -3
  143. data/vendor/libgit2/include/git2/revparse.h +22 -0
  144. data/vendor/libgit2/include/git2/stash.h +1 -1
  145. data/vendor/libgit2/include/git2/status.h +131 -56
  146. data/vendor/libgit2/include/git2/strarray.h +2 -2
  147. data/vendor/libgit2/include/git2/submodule.h +16 -16
  148. data/vendor/libgit2/include/git2/sys/commit.h +46 -0
  149. data/vendor/libgit2/include/git2/sys/config.h +71 -0
  150. data/vendor/libgit2/include/git2/sys/index.h +179 -0
  151. data/vendor/libgit2/include/git2/sys/odb_backend.h +86 -0
  152. data/vendor/libgit2/include/git2/sys/refdb_backend.h +158 -0
  153. data/vendor/libgit2/include/git2/sys/refs.h +38 -0
  154. data/vendor/libgit2/include/git2/sys/repository.h +106 -0
  155. data/vendor/libgit2/include/git2/tag.h +44 -18
  156. data/vendor/libgit2/include/git2/trace.h +1 -2
  157. data/vendor/libgit2/include/git2/transport.h +74 -0
  158. data/vendor/libgit2/include/git2/tree.h +12 -22
  159. data/vendor/libgit2/include/git2/types.h +33 -0
  160. data/vendor/libgit2/include/git2/version.h +2 -2
  161. data/vendor/libgit2/src/array.h +66 -0
  162. data/vendor/libgit2/src/attr.c +26 -13
  163. data/vendor/libgit2/src/attr_file.c +3 -2
  164. data/vendor/libgit2/src/attr_file.h +3 -3
  165. data/vendor/libgit2/src/attrcache.h +4 -4
  166. data/vendor/libgit2/src/blob.c +13 -9
  167. data/vendor/libgit2/src/blob.h +2 -2
  168. data/vendor/libgit2/src/branch.c +67 -49
  169. data/vendor/libgit2/src/cache.c +224 -54
  170. data/vendor/libgit2/src/cache.h +33 -20
  171. data/vendor/libgit2/src/checkout.c +145 -85
  172. data/vendor/libgit2/src/clone.c +62 -50
  173. data/vendor/libgit2/src/commit.c +74 -40
  174. data/vendor/libgit2/src/commit.h +2 -3
  175. data/vendor/libgit2/src/commit_list.c +14 -8
  176. data/vendor/libgit2/src/config.c +119 -36
  177. data/vendor/libgit2/src/config.h +3 -0
  178. data/vendor/libgit2/src/config_cache.c +24 -7
  179. data/vendor/libgit2/src/config_file.c +9 -6
  180. data/vendor/libgit2/src/crlf.c +4 -2
  181. data/vendor/libgit2/src/date.c +3 -3
  182. data/vendor/libgit2/src/delta.c +1 -1
  183. data/vendor/libgit2/src/diff.c +681 -303
  184. data/vendor/libgit2/src/diff.h +34 -2
  185. data/vendor/libgit2/src/diff_driver.c +405 -0
  186. data/vendor/libgit2/src/diff_driver.h +49 -0
  187. data/vendor/libgit2/src/diff_file.c +447 -0
  188. data/vendor/libgit2/src/diff_file.h +58 -0
  189. data/vendor/libgit2/src/diff_patch.c +995 -0
  190. data/vendor/libgit2/src/diff_patch.h +46 -0
  191. data/vendor/libgit2/src/diff_print.c +430 -0
  192. data/vendor/libgit2/src/diff_tform.c +464 -203
  193. data/vendor/libgit2/src/diff_xdiff.c +166 -0
  194. data/vendor/libgit2/src/diff_xdiff.h +28 -0
  195. data/vendor/libgit2/src/fetch.c +11 -4
  196. data/vendor/libgit2/src/fileops.c +85 -61
  197. data/vendor/libgit2/src/fileops.h +4 -0
  198. data/vendor/libgit2/src/global.c +10 -2
  199. data/vendor/libgit2/src/global.h +0 -8
  200. data/vendor/libgit2/src/hash/hash_generic.h +3 -3
  201. data/vendor/libgit2/src/hash/hash_win32.h +4 -4
  202. data/vendor/libgit2/src/hashsig.c +0 -1
  203. data/vendor/libgit2/src/ignore.c +68 -28
  204. data/vendor/libgit2/src/ignore.h +10 -1
  205. data/vendor/libgit2/src/index.c +666 -84
  206. data/vendor/libgit2/src/index.h +6 -0
  207. data/vendor/libgit2/src/indexer.c +10 -28
  208. data/vendor/libgit2/src/iterator.c +427 -283
  209. data/vendor/libgit2/src/iterator.h +58 -4
  210. data/vendor/libgit2/src/merge.c +1892 -32
  211. data/vendor/libgit2/src/merge.h +132 -5
  212. data/vendor/libgit2/src/merge_file.c +174 -0
  213. data/vendor/libgit2/src/merge_file.h +71 -0
  214. data/vendor/libgit2/src/mwindow.c +1 -1
  215. data/vendor/libgit2/src/notes.c +45 -48
  216. data/vendor/libgit2/src/object.c +89 -127
  217. data/vendor/libgit2/src/object.h +0 -1
  218. data/vendor/libgit2/src/object_api.c +129 -0
  219. data/vendor/libgit2/src/odb.c +156 -59
  220. data/vendor/libgit2/src/odb.h +5 -2
  221. data/vendor/libgit2/src/odb_loose.c +31 -17
  222. data/vendor/libgit2/src/odb_pack.c +39 -43
  223. data/vendor/libgit2/src/oid.c +62 -27
  224. data/vendor/libgit2/src/oid.h +33 -0
  225. data/vendor/libgit2/src/oidmap.h +4 -6
  226. data/vendor/libgit2/src/pack-objects.c +54 -22
  227. data/vendor/libgit2/src/pack.c +98 -56
  228. data/vendor/libgit2/src/pack.h +3 -1
  229. data/vendor/libgit2/src/pathspec.c +26 -1
  230. data/vendor/libgit2/src/pathspec.h +14 -0
  231. data/vendor/libgit2/src/pool.c +5 -0
  232. data/vendor/libgit2/src/posix.c +2 -2
  233. data/vendor/libgit2/src/posix.h +3 -0
  234. data/vendor/libgit2/src/push.c +13 -10
  235. data/vendor/libgit2/src/refdb.c +82 -62
  236. data/vendor/libgit2/src/refdb.h +16 -16
  237. data/vendor/libgit2/src/refdb_fs.c +386 -133
  238. data/vendor/libgit2/src/reflog.c +3 -1
  239. data/vendor/libgit2/src/refs.c +247 -221
  240. data/vendor/libgit2/src/refs.h +2 -1
  241. data/vendor/libgit2/src/refspec.c +18 -1
  242. data/vendor/libgit2/src/refspec.h +3 -1
  243. data/vendor/libgit2/src/remote.c +434 -253
  244. data/vendor/libgit2/src/remote.h +5 -3
  245. data/vendor/libgit2/src/repository.c +197 -111
  246. data/vendor/libgit2/src/repository.h +26 -5
  247. data/vendor/libgit2/src/reset.c +1 -1
  248. data/vendor/libgit2/src/revparse.c +84 -79
  249. data/vendor/libgit2/src/revwalk.c +1 -1
  250. data/vendor/libgit2/src/signature.c +22 -10
  251. data/vendor/libgit2/src/stash.c +5 -2
  252. data/vendor/libgit2/src/status.c +311 -107
  253. data/vendor/libgit2/src/status.h +23 -0
  254. data/vendor/libgit2/src/submodule.c +21 -13
  255. data/vendor/libgit2/src/tag.c +42 -31
  256. data/vendor/libgit2/src/tag.h +2 -3
  257. data/vendor/libgit2/src/thread-utils.h +105 -3
  258. data/vendor/libgit2/src/trace.c +1 -2
  259. data/vendor/libgit2/src/trace.h +3 -3
  260. data/vendor/libgit2/src/transport.c +18 -6
  261. data/vendor/libgit2/src/transports/cred.c +103 -1
  262. data/vendor/libgit2/src/transports/local.c +19 -9
  263. data/vendor/libgit2/src/transports/smart_protocol.c +32 -12
  264. data/vendor/libgit2/src/transports/ssh.c +519 -0
  265. data/vendor/libgit2/src/transports/winhttp.c +3 -1
  266. data/vendor/libgit2/src/tree.c +26 -28
  267. data/vendor/libgit2/src/tree.h +3 -3
  268. data/vendor/libgit2/src/unix/posix.h +2 -0
  269. data/vendor/libgit2/src/util.c +43 -6
  270. data/vendor/libgit2/src/util.h +40 -12
  271. data/vendor/libgit2/src/vector.c +3 -5
  272. data/vendor/libgit2/src/vector.h +9 -0
  273. data/vendor/libgit2/src/win32/dir.c +1 -1
  274. data/vendor/libgit2/src/win32/error.c +2 -0
  275. data/vendor/libgit2/src/win32/findfile.c +3 -6
  276. data/vendor/libgit2/src/win32/posix_w32.c +85 -59
  277. data/vendor/libgit2/src/win32/pthread.c +16 -8
  278. data/vendor/libgit2/src/win32/pthread.h +7 -4
  279. metadata +407 -306
  280. data/test/coverage/HEAD.json +0 -1
  281. data/vendor/libgit2/include/git2/refdb_backend.h +0 -109
  282. data/vendor/libgit2/src/diff_output.c +0 -1819
  283. data/vendor/libgit2/src/diff_output.h +0 -93
@@ -35,45 +35,82 @@ static void rb_git_remote__free(git_remote *remote)
35
35
 
36
36
  VALUE rugged_remote_new(VALUE klass, VALUE owner, git_remote *remote)
37
37
  {
38
- VALUE rb_remote = Data_Wrap_Struct(klass, NULL, &rb_git_remote__free, remote);
38
+ VALUE rb_remote;
39
+
40
+ rb_remote = Data_Wrap_Struct(klass, NULL, &rb_git_remote__free, remote);
39
41
  rugged_set_owner(rb_remote, owner);
40
42
  return rb_remote;
41
43
  }
42
44
 
45
+ static inline void rugged_validate_remote_url(VALUE rb_url)
46
+ {
47
+ Check_Type(rb_url, T_STRING);
48
+ if (!git_remote_valid_url(StringValueCStr(rb_url)))
49
+ rb_raise(rb_eArgError, "Invalid URL format");
50
+ }
51
+
43
52
  /*
44
- * call-seq:
45
- * Remote.new(repository, url) -> remote
53
+ * call-seq:
54
+ * Remote.new(repository, url) -> remote
46
55
  *
47
- * Return a new remote from +url+ in +repository+ , the remote is not persisted:
48
- * - +url+: a valid remote url
56
+ * Return a new remote with +url+ in +repository+ , the remote is not persisted:
57
+ * - +url+: a valid remote url
49
58
  *
50
- * Returns a new <tt>Rugged::Remote</tt> object
59
+ * Returns a new Rugged::Remote object
51
60
  *
52
- * Rugged::Remote.new(@repo, 'git://github.com/libgit2/libgit2.git') #=> #<Rugged::Remote:0x00000001fbfa80>
61
+ * Rugged::Remote.new(@repo, 'git://github.com/libgit2/libgit2.git') #=> #<Rugged::Remote:0x00000001fbfa80>
53
62
  */
54
63
  static VALUE rb_git_remote_new(VALUE klass, VALUE rb_repo, VALUE rb_url)
55
64
  {
56
65
  git_remote *remote;
57
66
  git_repository *repo;
58
- const char *url;
59
67
  int error;
60
68
 
61
- Check_Type(rb_url, T_STRING);
62
69
  rugged_check_repo(rb_repo);
70
+ rugged_validate_remote_url(rb_url);
63
71
 
64
72
  Data_Get_Struct(rb_repo, git_repository, repo);
65
73
 
66
- url = StringValueCStr(rb_url);
74
+ error = git_remote_create_inmemory(
75
+ &remote,
76
+ repo,
77
+ NULL,
78
+ StringValueCStr(rb_url));
67
79
 
68
- if (git_remote_valid_url(url)) {
69
- error = git_remote_create_inmemory(
70
- &remote,
71
- repo,
72
- NULL,
73
- url);
74
- } else {
75
- rb_raise(rb_eArgError, "Invalid URL format");
76
- }
80
+ rugged_exception_check(error);
81
+
82
+ return rugged_remote_new(klass, rb_repo, remote);
83
+ }
84
+
85
+ /*
86
+ * call-seq:
87
+ * Remote.add(repository, name, url) -> remote
88
+ *
89
+ * Add a new remote with +name+ and +url+ to +repository+
90
+ * - +url+: a valid remote url
91
+ * - +name+: a valid remote name
92
+ *
93
+ * Returns a new Rugged::Remote object
94
+ *
95
+ * Rugged::Remote.add(@repo, 'origin', 'git://github.com/libgit2/rugged.git') #=> #<Rugged::Remote:0x00000001fbfa80>
96
+ */
97
+ static VALUE rb_git_remote_add(VALUE klass, VALUE rb_repo,VALUE rb_name, VALUE rb_url)
98
+ {
99
+ git_remote *remote;
100
+ git_repository *repo;
101
+ int error;
102
+
103
+ Check_Type(rb_name, T_STRING);
104
+ rugged_validate_remote_url(rb_url);
105
+ rugged_check_repo(rb_repo);
106
+
107
+ Data_Get_Struct(rb_repo, git_repository, repo);
108
+
109
+ error = git_remote_create(
110
+ &remote,
111
+ repo,
112
+ StringValueCStr(rb_name),
113
+ StringValueCStr(rb_url));
77
114
 
78
115
  rugged_exception_check(error);
79
116
 
@@ -81,16 +118,16 @@ static VALUE rb_git_remote_new(VALUE klass, VALUE rb_repo, VALUE rb_url)
81
118
  }
82
119
 
83
120
  /*
84
- * call-seq:
85
- * Remote.lookup(repository, name) -> new_remote or nil
121
+ * call-seq:
122
+ * Remote.lookup(repository, name) -> remote or nil
86
123
  *
87
- * Return an existing remote with +name+ in +repository+:
88
- * - +name+: a valid remote name
124
+ * Return an existing remote with +name+ in +repository+:
125
+ * - +name+: a valid remote name
89
126
  *
90
- * Returns a new <tt>Rugged::Remote</tt> object or +nil+ if the
91
- * remote doesn't exist
127
+ * Returns a new Rugged::Remote object or +nil+ if the
128
+ * remote doesn't exist
92
129
  *
93
- * Rugged::Remote.lookup(@repo, 'origin') #=> #<Rugged::Remote:0x00000001fbfa80>
130
+ * Rugged::Remote.lookup(@repo, 'origin') #=> #<Rugged::Remote:0x00000001fbfa80>
94
131
  */
95
132
  static VALUE rb_git_remote_lookup(VALUE klass, VALUE rb_repo, VALUE rb_name)
96
133
  {
@@ -112,6 +149,12 @@ static VALUE rb_git_remote_lookup(VALUE klass, VALUE rb_repo, VALUE rb_name)
112
149
  return rugged_remote_new(klass, rb_repo, remote);
113
150
  }
114
151
 
152
+ /*
153
+ * call-seq:
154
+ * remote.disconnect() -> nil
155
+ *
156
+ * Disconnect from the remote, closes the connection to the remote
157
+ */
115
158
  static VALUE rb_git_remote_disconnect(VALUE self)
116
159
  {
117
160
  git_remote *remote;
@@ -121,9 +164,29 @@ static VALUE rb_git_remote_disconnect(VALUE self)
121
164
  return Qnil;
122
165
  }
123
166
 
167
+ /*
168
+ * call-seq:
169
+ * remote.connect(direction) -> nil
170
+ * remote.connect(direction) { |connected_remote| block }
171
+ *
172
+ * Open a connection to a remote:
173
+ * - +direction+: +:fetch+ or +:pull+
174
+ *
175
+ * If a block is given it will be passed the connected remote as argument
176
+ * and the remote will be disconnected when the block terminates.
177
+ *
178
+ * The transport is selected based on the URL.
179
+ *
180
+ * remote.connect(:fetch) #=> nil
181
+ *
182
+ * remote.connect(:fetch) do |r|
183
+ * r.connected? #=> true
184
+ * end
185
+ *
186
+ */
124
187
  static VALUE rb_git_remote_connect(VALUE self, VALUE rb_direction)
125
188
  {
126
- int error, direction = 0;
189
+ int error, direction = 0, exception = 0;
127
190
  git_remote *remote;
128
191
  ID id_direction;
129
192
 
@@ -143,8 +206,13 @@ static VALUE rb_git_remote_connect(VALUE self, VALUE rb_direction)
143
206
  error = git_remote_connect(remote, direction);
144
207
  rugged_exception_check(error);
145
208
 
146
- if (rb_block_given_p())
147
- rb_ensure(rb_yield, self, rb_git_remote_disconnect, self);
209
+ if (rb_block_given_p()) {
210
+ rb_protect(rb_yield, self, &exception);
211
+ git_remote_disconnect(remote);
212
+
213
+ if (exception)
214
+ rb_jump_tag(exception);
215
+ }
148
216
 
149
217
  return Qnil;
150
218
  }
@@ -155,33 +223,67 @@ static VALUE rugged_rhead_new(git_remote_head *head)
155
223
 
156
224
  rb_hash_aset(rb_head, CSTR2SYM("local?"), head->local ? Qtrue : Qfalse);
157
225
  rb_hash_aset(rb_head, CSTR2SYM("oid"), rugged_create_oid(&head->oid));
158
- rb_hash_aset(rb_head, CSTR2SYM("loid"), rugged_create_oid(&head->loid));
159
- rb_hash_aset(rb_head, CSTR2SYM("name"), rugged_str_new2(head->name, NULL));
226
+ rb_hash_aset(rb_head, CSTR2SYM("loid"),
227
+ git_oid_iszero(&head->loid) ? Qnil : rugged_create_oid(&head->loid));
228
+ rb_hash_aset(rb_head, CSTR2SYM("name"), rb_str_new_utf8(head->name));
160
229
 
161
230
  return rb_head;
162
231
  }
163
232
 
164
233
  static int cb_remote__ls(git_remote_head *head, void *payload)
165
234
  {
166
- rb_funcall((VALUE)payload, rb_intern("call"), 1, rugged_rhead_new(head));
167
- return GIT_OK;
235
+ int *exception = (int *)payload;
236
+ rb_protect(rb_yield, rugged_rhead_new(head), exception);
237
+ return *exception ? GIT_ERROR : GIT_OK;
168
238
  }
169
239
 
240
+ /*
241
+ * call-seq:
242
+ * remote.ls() -> an_enumerator
243
+ * remote.ls() { |remote_head_hash| block }
244
+ *
245
+ * List references available in a connected +remote+ repository along
246
+ * with the associated commit IDs.
247
+ *
248
+ * Call the given block once for each remote head in the +remote+ as a
249
+ * +Hash+.
250
+ * If no block is given an Enumerator is returned.
251
+ *
252
+ * remote.connect(:fetch) do |r|
253
+ * r.ls.to_a #=> [{:local?=>false, :oid=>"b3ee97a91b02e91c35394950bda6ea622044baad", :loid=> nil, :name=>"refs/heads/development"}]
254
+ * end
255
+ *
256
+ * remote head hash includes:
257
+ * [:oid] oid of the remote head
258
+ * [:name] name of the remote head
259
+ *
260
+ *
261
+ */
170
262
  static VALUE rb_git_remote_ls(VALUE self)
171
263
  {
172
- int error;
264
+ int error, exception = 0;
173
265
  git_remote *remote;
174
266
  Data_Get_Struct(self, git_remote, remote);
175
267
 
176
268
  if (!rb_block_given_p())
177
269
  return rb_funcall(self, rb_intern("to_enum"), 1, CSTR2SYM("ls"));
178
270
 
179
- error = git_remote_ls(remote, &cb_remote__ls, (void *)rb_block_proc());
271
+ error = git_remote_ls(remote, &cb_remote__ls, &exception);
272
+
273
+ if (exception)
274
+ rb_jump_tag(exception);
180
275
  rugged_exception_check(error);
181
276
 
182
277
  return Qnil;
183
278
  }
184
279
 
280
+ /*
281
+ * call-seq:
282
+ * remote.name() -> string
283
+ *
284
+ * Returns the remote's name
285
+ * remote.name #=> "origin"
286
+ */
185
287
  static VALUE rb_git_remote_name(VALUE self)
186
288
  {
187
289
  git_remote *remote;
@@ -190,20 +292,197 @@ static VALUE rb_git_remote_name(VALUE self)
190
292
 
191
293
  name = git_remote_name(remote);
192
294
 
193
- if (name)
194
- return rugged_str_new2(name, NULL);
195
- else
196
- return Qnil;
295
+ return name ? rb_str_new_utf8(name) : Qnil;
197
296
  }
198
297
 
298
+ /*
299
+ * call-seq:
300
+ * remote.url() -> string
301
+ *
302
+ * Returns the remote's url
303
+ * remote.url #=> "git://github.com/libgit2/rugged.git"
304
+ */
199
305
  static VALUE rb_git_remote_url(VALUE self)
200
306
  {
201
307
  git_remote *remote;
202
308
  Data_Get_Struct(self, git_remote, remote);
203
309
 
204
- return rugged_str_new2(git_remote_url(remote), NULL);
310
+ return rb_str_new_utf8(git_remote_url(remote));
311
+ }
312
+
313
+ /*
314
+ * call-seq:
315
+ * remote.url = url -> url
316
+ *
317
+ * Sets the remote's url without persisting it in the config.
318
+ * Existing connections will not be updated.
319
+ * remote.url = 'git://github.com/libgit2/rugged.git' #=> "git://github.com/libgit2/rugged.git"
320
+ */
321
+ static VALUE rb_git_remote_set_url(VALUE self, VALUE rb_url)
322
+ {
323
+ git_remote *remote;
324
+
325
+ rugged_validate_remote_url(rb_url);
326
+ Data_Get_Struct(self, git_remote, remote);
327
+
328
+ rugged_exception_check(
329
+ git_remote_set_url(remote, StringValueCStr(rb_url))
330
+ );
331
+ return rb_url;
332
+ }
333
+
334
+ /*
335
+ * call-seq:
336
+ * remote.push_url() -> string or nil
337
+ *
338
+ * Returns the remote's url for pushing or nil if no special url for
339
+ * pushing is set.
340
+ * remote.push_url #=> "git://github.com/libgit2/rugged.git"
341
+ */
342
+ static VALUE rb_git_remote_push_url(VALUE self)
343
+ {
344
+ git_remote *remote;
345
+ const char * push_url;
346
+
347
+ Data_Get_Struct(self, git_remote, remote);
348
+
349
+ push_url = git_remote_pushurl(remote);
350
+ return push_url ? rb_str_new_utf8(push_url) : Qnil;
205
351
  }
206
352
 
353
+ /*
354
+ * call-seq:
355
+ * remote.push_url = url -> url
356
+ *
357
+ * Sets the remote's url for pushing without persisting it in the config.
358
+ * Existing connections will not be updated.
359
+ * remote.push_url = 'git@github.com/libgit2/rugged.git' #=> "git@github.com/libgit2/rugged.git"
360
+ */
361
+ static VALUE rb_git_remote_set_push_url(VALUE self, VALUE rb_url)
362
+ {
363
+ git_remote *remote;
364
+
365
+ rugged_validate_remote_url(rb_url);
366
+ Data_Get_Struct(self, git_remote, remote);
367
+
368
+ rugged_exception_check(
369
+ git_remote_set_pushurl(remote, StringValueCStr(rb_url))
370
+ );
371
+
372
+ return rb_url;
373
+ }
374
+
375
+ static VALUE rb_git_remote_refspecs(VALUE self, git_direction direction)
376
+ {
377
+ git_remote *remote;
378
+ int error = 0;
379
+ git_strarray refspecs;
380
+ VALUE rb_refspec_array;
381
+
382
+ Data_Get_Struct(self, git_remote, remote);
383
+
384
+ if (direction == GIT_DIRECTION_FETCH)
385
+ error = git_remote_get_fetch_refspecs(&refspecs, remote);
386
+ else
387
+ error = git_remote_get_push_refspecs(&refspecs, remote);
388
+
389
+ rugged_exception_check(error);
390
+
391
+ rb_refspec_array = rugged_strarray_to_rb_ary(&refspecs);
392
+ git_strarray_free(&refspecs);
393
+ return rb_refspec_array;
394
+ }
395
+
396
+ /*
397
+ * call-seq:
398
+ * remote.fetch_refspecs -> array
399
+ *
400
+ * Get the remote's list of fetch refspecs as +array+
401
+ */
402
+ static VALUE rb_git_remote_fetch_refspecs(VALUE self)
403
+ {
404
+ return rb_git_remote_refspecs(self, GIT_DIRECTION_FETCH);
405
+ }
406
+
407
+ /*
408
+ * call-seq:
409
+ * remote.push_refspecs -> array
410
+ *
411
+ * Get the remote's list of push refspecs as +array+
412
+ */
413
+ static VALUE rb_git_remote_push_refspecs(VALUE self)
414
+ {
415
+ return rb_git_remote_refspecs(self, GIT_DIRECTION_PUSH);
416
+ }
417
+
418
+ static VALUE rb_git_remote_add_refspec(VALUE self, VALUE rb_refspec, git_direction direction)
419
+ {
420
+ git_remote *remote;
421
+ int error = 0;
422
+
423
+ Data_Get_Struct(self, git_remote, remote);
424
+
425
+ Check_Type(rb_refspec, T_STRING);
426
+
427
+ if (direction == GIT_DIRECTION_FETCH)
428
+ error = git_remote_add_fetch(remote, StringValueCStr(rb_refspec));
429
+ else
430
+ error = git_remote_add_push(remote, StringValueCStr(rb_refspec));
431
+
432
+ rugged_exception_check(error);
433
+
434
+ return Qnil;
435
+ }
436
+
437
+ /*
438
+ * call-seq:
439
+ * remote.add_fetch(refspec) -> nil
440
+ *
441
+ * Add a fetch refspec to the remote
442
+ */
443
+ static VALUE rb_git_remote_add_fetch(VALUE self, VALUE rb_refspec)
444
+ {
445
+ return rb_git_remote_add_refspec(self, rb_refspec, GIT_DIRECTION_FETCH);
446
+ }
447
+
448
+ /*
449
+ * call-seq:
450
+ * remote.add_push(refspec) -> nil
451
+ *
452
+ * Add a push refspec to the remote
453
+ */
454
+ static VALUE rb_git_remote_add_push(VALUE self, VALUE rb_refspec)
455
+ {
456
+ return rb_git_remote_add_refspec(self, rb_refspec, GIT_DIRECTION_PUSH);
457
+ }
458
+
459
+ /*
460
+ * call-seq:
461
+ * remote.clear_refspecs -> nil
462
+ *
463
+ * Remove all configured fetch and push refspecs from the remote.
464
+ */
465
+ static VALUE rb_git_remote_clear_refspecs(VALUE self)
466
+ {
467
+ git_remote *remote;
468
+
469
+ Data_Get_Struct(self, git_remote, remote);
470
+
471
+ git_remote_clear_refspecs(remote);
472
+
473
+ return Qnil;
474
+ }
475
+
476
+ /*
477
+ * call-seq:
478
+ * remote.connected? -> true or false
479
+ *
480
+ * Returns if the remote is connected
481
+ *
482
+ * remote.connected? #=> false
483
+ * remote.connect(:fetch)
484
+ * remote.connected? #=> true
485
+ */
207
486
  static VALUE rb_git_remote_connected(VALUE self)
208
487
  {
209
488
  git_remote *remote;
@@ -212,6 +491,19 @@ static VALUE rb_git_remote_connected(VALUE self)
212
491
  return git_remote_connected(remote) ? Qtrue : Qfalse;
213
492
  }
214
493
 
494
+ /*
495
+ * call-seq:
496
+ * remote.download() -> nil
497
+ *
498
+ * Download the packfile from a connected remote
499
+ *
500
+ * Negotiate what objects should be downloaded and download the
501
+ * packfile with those objects.
502
+ *
503
+ * remote.connect(:fetch) do |r|
504
+ * r.download
505
+ * end
506
+ */
215
507
  static VALUE rb_git_remote_download(VALUE self)
216
508
  {
217
509
  int error;
@@ -225,59 +517,223 @@ static VALUE rb_git_remote_download(VALUE self)
225
517
  return Qnil;
226
518
  }
227
519
 
520
+ static int cb_remote__update_tips(const char *refname, const git_oid *src, const git_oid *dest, void *payload)
521
+ {
522
+ VALUE rb_args = rb_ary_new2(3);
523
+ int *exception = (int *)payload;
524
+ rb_ary_push(rb_args, rb_str_new_utf8(refname));
525
+ rb_ary_push(rb_args, git_oid_iszero(src) ? Qnil : rugged_create_oid(src));
526
+ rb_ary_push(rb_args, git_oid_iszero(dest) ? Qnil : rugged_create_oid(dest));
527
+
528
+ rb_protect(rb_yield_splat, rb_args, exception);
529
+
530
+ return *exception ? GIT_ERROR : GIT_OK;
531
+ }
532
+
533
+ /*
534
+ * call-seq:
535
+ * remote.update_tips! -> nil
536
+ * remote.update_tips! { |reference, source, destination| block }
537
+ *
538
+ * Update the tips to a new state from a connected remote. The target
539
+ * objects must be downloaded before the tips are updated.
540
+ *
541
+ * r.update_tips! do |ref, src, dst|
542
+ * puts "#{ref}: #{src}..#{dst}"
543
+ * end
544
+ */
228
545
  static VALUE rb_git_remote_update_tips(VALUE self)
229
546
  {
230
- int error;
231
547
  git_remote *remote;
232
548
 
233
549
  Data_Get_Struct(self, git_remote, remote);
234
550
 
235
- // TODO: Maybe allow passing down a block?
236
- error = git_remote_update_tips(remote);
237
- rugged_exception_check(error);
551
+ if (rb_block_given_p()) {
552
+ int exception = 0, error;
553
+ git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT;
554
+
555
+ callbacks.payload = &exception;
556
+ callbacks.update_tips = &cb_remote__update_tips;
557
+ rugged_exception_check(
558
+ git_remote_set_callbacks(remote, &callbacks)
559
+ );
560
+
561
+ error = git_remote_update_tips(remote);
562
+
563
+ callbacks.update_tips = NULL;
564
+ // Don't overwrite the first error we've seen
565
+ if (!error) error = git_remote_set_callbacks(remote, &callbacks);
566
+ else git_remote_set_callbacks(remote, &callbacks);
567
+
568
+ if (exception)
569
+ rb_jump_tag(exception);
570
+
571
+ rugged_exception_check(error);
572
+ } else {
573
+ rugged_exception_check(
574
+ git_remote_update_tips(remote)
575
+ );
576
+ }
238
577
 
239
578
  return Qnil;
240
579
  }
241
580
 
242
- static VALUE rb_git_remote_each(VALUE self, VALUE rb_repo)
581
+ /*
582
+ * call-seq:
583
+ * Remote.names(repository) -> array
584
+ *
585
+ * Returns the names of all remotes in +repository+
586
+ *
587
+ * Rugged::Remote.names(@repo) #=> ['origin', 'upstream']
588
+ */
589
+
590
+ static VALUE rb_git_remote_names(VALUE klass, VALUE rb_repo)
243
591
  {
244
592
  git_repository *repo;
245
593
  git_strarray remotes;
246
- size_t i;
594
+ VALUE rb_remote_names;
247
595
  int error;
248
596
 
249
- if (!rb_block_given_p())
250
- return rb_funcall(self, rb_intern("to_enum"), 2, CSTR2SYM("each"), rb_repo);
597
+ rugged_check_repo(rb_repo);
251
598
 
252
- if (!rb_obj_is_kind_of(rb_repo, rb_cRuggedRepo))
253
- rb_raise(rb_eTypeError, "Expeting a Rugged::Repository instance");
599
+ Data_Get_Struct(rb_repo, git_repository, repo);
254
600
 
601
+ error = git_remote_list(&remotes, repo);
602
+ rugged_exception_check(error);
603
+
604
+ rb_remote_names = rugged_strarray_to_rb_ary(&remotes);
605
+ git_strarray_free(&remotes);
606
+ return rb_remote_names;
607
+ }
608
+
609
+ /* :nodoc: */
610
+ static VALUE rb_git_remote_each(VALUE klass, VALUE rb_repo)
611
+ {
612
+ git_repository *repo;
613
+ git_strarray remotes;
614
+ size_t i;
615
+ int error = 0;
616
+ int exception = 0;
617
+
618
+ if (!rb_block_given_p())
619
+ return rb_funcall(klass, rb_intern("to_enum"), 2, CSTR2SYM("each"), rb_repo);
620
+
621
+ rugged_check_repo(rb_repo);
255
622
  Data_Get_Struct(rb_repo, git_repository, repo);
256
623
 
257
624
  error = git_remote_list(&remotes, repo);
258
625
  rugged_exception_check(error);
259
626
 
260
- for (i = 0; i < remotes.count; ++i)
261
- rb_yield(rugged_str_new2(remotes.strings[i], NULL));
627
+ for (i = 0; !exception && !error && i < remotes.count; ++i) {
628
+ git_remote *remote;
629
+ error = git_remote_load(&remote, repo, remotes.strings[i]);
630
+
631
+ if (!error) {
632
+ rb_protect(
633
+ rb_yield, rugged_remote_new(klass, rb_repo, remote),
634
+ &exception);
635
+ }
636
+ }
262
637
 
263
638
  git_strarray_free(&remotes);
639
+
640
+ if (exception)
641
+ rb_jump_tag(exception);
642
+
643
+ rugged_exception_check(error);
264
644
  return Qnil;
265
645
  }
266
646
 
267
- void Init_rugged_remote()
647
+ /*
648
+ * call-seq:
649
+ * remote.save -> true
650
+ *
651
+ * Saves the remote data ( url, fetchspecs, ...) to the config
652
+ *
653
+ * One can't save a in-memory remote created with Remote.new.
654
+ * Doing so will result in an exception being raised.
655
+ */
656
+ static VALUE rb_git_remote_save(VALUE self)
657
+ {
658
+ git_remote *remote;
659
+
660
+ Data_Get_Struct(self, git_remote, remote);
661
+
662
+ rugged_exception_check(
663
+ git_remote_save(remote)
664
+ );
665
+ return Qtrue;
666
+ }
667
+
668
+ static int cb_remote__rename_problem(const char* refspec_name, void *payload)
669
+ {
670
+ rb_ary_push((VALUE) payload, rb_str_new_utf8(refspec_name));
671
+ return 0;
672
+ }
673
+
674
+ /*
675
+ * call-seq:
676
+ * remote.rename!(new_name) -> array or nil
677
+ *
678
+ * Renames a remote
679
+ *
680
+ * All remote-tracking branches and configuration settings
681
+ * for the remote are updated.
682
+ *
683
+ * Returns +nil+ if everything was updated or array of fetch refspecs
684
+ * that haven't been automatically updated and need potential manual
685
+ * tweaking.
686
+ *
687
+ * A temporary in-memory remote, created with Remote.new
688
+ * cannot be given a name with this method.
689
+ * remote = Rugged::Remote.lookup(@repo, 'origin')
690
+ * remote.rename!('upstream') #=> nil
691
+ *
692
+ */
693
+ static VALUE rb_git_remote_rename(VALUE self, VALUE rb_new_name)
694
+ {
695
+ git_remote *remote;
696
+ int error = 0;
697
+ VALUE rb_refspec_ary = rb_ary_new();
698
+
699
+ Check_Type(rb_new_name, T_STRING);
700
+ Data_Get_Struct(self, git_remote, remote);
701
+ error = git_remote_rename(
702
+ remote,
703
+ StringValueCStr(rb_new_name),
704
+ cb_remote__rename_problem, (void *)rb_refspec_ary);
705
+
706
+ rugged_exception_check(error);
707
+
708
+ return RARRAY_LEN(rb_refspec_ary) == 0 ? Qnil : rb_refspec_ary;
709
+ }
710
+
711
+ void Init_rugged_remote(void)
268
712
  {
269
713
  rb_cRuggedRemote = rb_define_class_under(rb_mRugged, "Remote", rb_cObject);
270
714
 
271
715
  rb_define_singleton_method(rb_cRuggedRemote, "new", rb_git_remote_new, 2);
716
+ rb_define_singleton_method(rb_cRuggedRemote, "add", rb_git_remote_add, 3);
272
717
  rb_define_singleton_method(rb_cRuggedRemote, "lookup", rb_git_remote_lookup, 2);
718
+ rb_define_singleton_method(rb_cRuggedRemote, "names", rb_git_remote_names, 1);
273
719
  rb_define_singleton_method(rb_cRuggedRemote, "each", rb_git_remote_each, 1);
274
720
 
275
721
  rb_define_method(rb_cRuggedRemote, "connect", rb_git_remote_connect, 1);
276
722
  rb_define_method(rb_cRuggedRemote, "disconnect", rb_git_remote_disconnect, 0);
277
723
  rb_define_method(rb_cRuggedRemote, "name", rb_git_remote_name, 0);
278
724
  rb_define_method(rb_cRuggedRemote, "url", rb_git_remote_url, 0);
725
+ rb_define_method(rb_cRuggedRemote, "url=", rb_git_remote_set_url, 1);
726
+ rb_define_method(rb_cRuggedRemote, "push_url", rb_git_remote_push_url, 0);
727
+ rb_define_method(rb_cRuggedRemote, "push_url=", rb_git_remote_set_push_url, 1);
728
+ rb_define_method(rb_cRuggedRemote, "fetch_refspecs", rb_git_remote_fetch_refspecs, 0);
729
+ rb_define_method(rb_cRuggedRemote, "push_refspecs", rb_git_remote_push_refspecs, 0);
730
+ rb_define_method(rb_cRuggedRemote, "add_fetch", rb_git_remote_add_fetch, 1);
731
+ rb_define_method(rb_cRuggedRemote, "add_push", rb_git_remote_add_push, 1);
279
732
  rb_define_method(rb_cRuggedRemote, "connected?", rb_git_remote_connected, 0);
280
733
  rb_define_method(rb_cRuggedRemote, "ls", rb_git_remote_ls, 0);
281
734
  rb_define_method(rb_cRuggedRemote, "download", rb_git_remote_download, 0);
282
735
  rb_define_method(rb_cRuggedRemote, "update_tips!", rb_git_remote_update_tips, 0);
736
+ rb_define_method(rb_cRuggedRemote, "clear_refspecs", rb_git_remote_clear_refspecs, 0);
737
+ rb_define_method(rb_cRuggedRemote, "save", rb_git_remote_save, 0);
738
+ rb_define_method(rb_cRuggedRemote, "rename!", rb_git_remote_rename, 1);
283
739
  }