rdavila-rugged 0.24.0b13

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/README.md +619 -0
  4. data/ext/rugged/extconf.rb +105 -0
  5. data/ext/rugged/rugged.c +527 -0
  6. data/ext/rugged/rugged.h +185 -0
  7. data/ext/rugged/rugged_backend.c +34 -0
  8. data/ext/rugged/rugged_blame.c +292 -0
  9. data/ext/rugged/rugged_blob.c +638 -0
  10. data/ext/rugged/rugged_branch.c +195 -0
  11. data/ext/rugged/rugged_branch_collection.c +408 -0
  12. data/ext/rugged/rugged_commit.c +691 -0
  13. data/ext/rugged/rugged_config.c +404 -0
  14. data/ext/rugged/rugged_cred.c +148 -0
  15. data/ext/rugged/rugged_diff.c +686 -0
  16. data/ext/rugged/rugged_diff_delta.c +105 -0
  17. data/ext/rugged/rugged_diff_hunk.c +103 -0
  18. data/ext/rugged/rugged_diff_line.c +83 -0
  19. data/ext/rugged/rugged_index.c +1255 -0
  20. data/ext/rugged/rugged_note.c +376 -0
  21. data/ext/rugged/rugged_object.c +383 -0
  22. data/ext/rugged/rugged_patch.c +245 -0
  23. data/ext/rugged/rugged_reference.c +396 -0
  24. data/ext/rugged/rugged_reference_collection.c +446 -0
  25. data/ext/rugged/rugged_remote.c +691 -0
  26. data/ext/rugged/rugged_remote_collection.c +457 -0
  27. data/ext/rugged/rugged_repo.c +2669 -0
  28. data/ext/rugged/rugged_revwalk.c +495 -0
  29. data/ext/rugged/rugged_settings.c +155 -0
  30. data/ext/rugged/rugged_signature.c +106 -0
  31. data/ext/rugged/rugged_submodule.c +852 -0
  32. data/ext/rugged/rugged_submodule_collection.c +384 -0
  33. data/ext/rugged/rugged_tag.c +251 -0
  34. data/ext/rugged/rugged_tag_collection.c +347 -0
  35. data/ext/rugged/rugged_tree.c +919 -0
  36. data/lib/rugged.rb +23 -0
  37. data/lib/rugged/attributes.rb +41 -0
  38. data/lib/rugged/blob.rb +28 -0
  39. data/lib/rugged/branch.rb +19 -0
  40. data/lib/rugged/commit.rb +54 -0
  41. data/lib/rugged/console.rb +9 -0
  42. data/lib/rugged/credentials.rb +43 -0
  43. data/lib/rugged/diff.rb +20 -0
  44. data/lib/rugged/diff/delta.rb +53 -0
  45. data/lib/rugged/diff/hunk.rb +18 -0
  46. data/lib/rugged/diff/line.rb +47 -0
  47. data/lib/rugged/index.rb +13 -0
  48. data/lib/rugged/object.rb +7 -0
  49. data/lib/rugged/patch.rb +36 -0
  50. data/lib/rugged/reference.rb +7 -0
  51. data/lib/rugged/remote.rb +4 -0
  52. data/lib/rugged/repository.rb +227 -0
  53. data/lib/rugged/submodule_collection.rb +48 -0
  54. data/lib/rugged/tag.rb +50 -0
  55. data/lib/rugged/tree.rb +38 -0
  56. data/lib/rugged/version.rb +3 -0
  57. data/lib/rugged/walker.rb +5 -0
  58. metadata +146 -0
@@ -0,0 +1,195 @@
1
+ /*
2
+ * The MIT License
3
+ *
4
+ * Copyright (c) 2014 GitHub, Inc
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ * of this software and associated documentation files (the "Software"), to deal
8
+ * in the Software without restriction, including without limitation the rights
9
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ * copies of the Software, and to permit persons to whom the Software is
11
+ * furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be included in
14
+ * all copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ * THE SOFTWARE.
23
+ */
24
+
25
+ #include "rugged.h"
26
+
27
+ extern VALUE rb_mRugged;
28
+ extern VALUE rb_cRuggedRepo;
29
+ extern VALUE rb_cRuggedObject;
30
+ extern VALUE rb_cRuggedReference;
31
+ VALUE rb_cRuggedBranch;
32
+
33
+ static inline VALUE rugged_branch_new(VALUE owner, git_reference *ref)
34
+ {
35
+ return rugged_ref_new(rb_cRuggedBranch, owner, ref);
36
+ }
37
+
38
+ /*
39
+ * call-seq:
40
+ * branch.head? -> true or false
41
+ *
42
+ * Returns +true+ if the branch is pointed at by +HEAD+, +false+ otherwise.
43
+ */
44
+ static VALUE rb_git_branch_head_p(VALUE self)
45
+ {
46
+ git_reference *branch;
47
+ Data_Get_Struct(self, git_reference, branch);
48
+ return git_branch_is_head(branch) ? Qtrue : Qfalse;
49
+ }
50
+
51
+ /*
52
+ * call-seq:
53
+ * branch.name -> string
54
+ *
55
+ * Returns the name of +branch+.
56
+ *
57
+ * See Rugged::Reference#canonical_name if you need the fully qualified
58
+ * name of the underlying reference.
59
+ */
60
+ static VALUE rb_git_branch_name(VALUE self)
61
+ {
62
+ git_reference *branch;
63
+ const char *branch_name;
64
+ Data_Get_Struct(self, git_reference, branch);
65
+
66
+ rugged_exception_check(git_branch_name(&branch_name, branch));
67
+
68
+ return rb_str_new_utf8(branch_name);
69
+ }
70
+
71
+ static VALUE rb_git_branch__remote_name(VALUE rb_repo, const char *canonical_name)
72
+ {
73
+ git_repository *repo;
74
+ git_buf remote_name = { NULL };
75
+ int error;
76
+ VALUE result = Qnil;
77
+
78
+ Data_Get_Struct(rb_repo, git_repository, repo);
79
+
80
+ if ((error = git_branch_remote_name(&remote_name, repo, canonical_name)) == GIT_OK)
81
+ result = rb_enc_str_new(remote_name.ptr, remote_name.size, rb_utf8_encoding());
82
+
83
+ git_buf_free(&remote_name);
84
+ rugged_exception_check(error);
85
+
86
+ return result;
87
+ }
88
+
89
+ /*
90
+ * call-seq:
91
+ * branch.remote_name -> string
92
+ *
93
+ * Get the name of the remote the branch belongs to.
94
+ *
95
+ * If +branch+ is a remote branch, the name of the remote it belongs to is
96
+ * returned. If +branch+ is a tracking branch, the name of the remote
97
+ * of the tracked branch is returned.
98
+ *
99
+ * Otherwise, +nil+ is returned.
100
+ */
101
+ static VALUE rb_git_branch_remote_name(VALUE self)
102
+ {
103
+ git_reference *branch, *remote_ref;
104
+ int error = 0;
105
+
106
+ Data_Get_Struct(self, git_reference, branch);
107
+
108
+ if (git_reference_is_remote(branch)) {
109
+ remote_ref = branch;
110
+ } else {
111
+ error = git_branch_upstream(&remote_ref, branch);
112
+
113
+ if (error == GIT_ENOTFOUND)
114
+ return Qnil;
115
+
116
+ rugged_exception_check(error);
117
+ }
118
+
119
+ return rb_git_branch__remote_name(
120
+ rugged_owner(self),
121
+ git_reference_name(remote_ref));
122
+ }
123
+
124
+ /*
125
+ * call-seq:
126
+ * branch.upstream -> branch
127
+ *
128
+ * Returns the remote tracking branch, or +nil+ if the branch is
129
+ * remote or has no tracking branch.
130
+ */
131
+ static VALUE rb_git_branch_upstream(VALUE self)
132
+ {
133
+ git_reference *branch, *upstream_branch;
134
+ int error;
135
+
136
+ Data_Get_Struct(self, git_reference, branch);
137
+
138
+ if (git_reference_is_remote(branch))
139
+ return Qnil;
140
+
141
+ error = git_branch_upstream(&upstream_branch, branch);
142
+
143
+ if (error == GIT_ENOTFOUND)
144
+ return Qnil;
145
+
146
+ rugged_exception_check(error);
147
+
148
+ return rugged_branch_new(rugged_owner(self), upstream_branch);
149
+ }
150
+
151
+ /*
152
+ * call-seq:
153
+ * branch.upstream = branch
154
+ *
155
+ * Set the upstream configuration for a given local branch.
156
+ *
157
+ * Takes a local or remote Rugged::Branch instance or a Rugged::Reference
158
+ * pointing to a branch.
159
+ */
160
+ static VALUE rb_git_branch_set_upstream(VALUE self, VALUE rb_branch)
161
+ {
162
+ git_reference *branch, *target_branch;
163
+ const char *target_branch_name;
164
+
165
+ Data_Get_Struct(self, git_reference, branch);
166
+ if (!NIL_P(rb_branch)) {
167
+ if (!rb_obj_is_kind_of(rb_branch, rb_cRuggedReference))
168
+ rb_raise(rb_eTypeError, "Expecting a Rugged::Reference instance");
169
+
170
+ Data_Get_Struct(rb_branch, git_reference, target_branch);
171
+
172
+ rugged_exception_check(
173
+ git_branch_name(&target_branch_name, target_branch)
174
+ );
175
+ } else {
176
+ target_branch_name = NULL;
177
+ }
178
+
179
+ rugged_exception_check(
180
+ git_branch_set_upstream(branch, target_branch_name)
181
+ );
182
+
183
+ return rb_branch;
184
+ }
185
+
186
+ void Init_rugged_branch(void)
187
+ {
188
+ rb_cRuggedBranch = rb_define_class_under(rb_mRugged, "Branch", rb_cRuggedReference);
189
+
190
+ rb_define_method(rb_cRuggedBranch, "head?", rb_git_branch_head_p, 0);
191
+ rb_define_method(rb_cRuggedBranch, "name", rb_git_branch_name, 0);
192
+ rb_define_method(rb_cRuggedBranch, "remote_name", rb_git_branch_remote_name, 0);
193
+ rb_define_method(rb_cRuggedBranch, "upstream", rb_git_branch_upstream, 0);
194
+ rb_define_method(rb_cRuggedBranch, "upstream=", rb_git_branch_set_upstream, 1);
195
+ }
@@ -0,0 +1,408 @@
1
+ /*
2
+ * The MIT License
3
+ *
4
+ * Copyright (c) 2014 GitHub, Inc
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ * of this software and associated documentation files (the "Software"), to deal
8
+ * in the Software without restriction, including without limitation the rights
9
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ * copies of the Software, and to permit persons to whom the Software is
11
+ * furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be included in
14
+ * all copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ * THE SOFTWARE.
23
+ */
24
+
25
+ #include "rugged.h"
26
+
27
+ extern VALUE rb_mRugged;
28
+ extern VALUE rb_cRuggedRepo;
29
+ extern VALUE rb_cRuggedBranch;
30
+
31
+ VALUE rb_cRuggedBranchCollection;
32
+
33
+ static inline VALUE rugged_branch_new(VALUE owner, git_reference *ref)
34
+ {
35
+ return rugged_ref_new(rb_cRuggedBranch, owner, ref);
36
+ }
37
+
38
+ // Helper method to normalize branch lookups.
39
+ static inline int rugged_branch_lookup(git_reference **branch, git_repository *repo, VALUE rb_name_or_branch)
40
+ {
41
+ if (rb_obj_is_kind_of(rb_name_or_branch, rb_cRuggedBranch)) {
42
+ rb_name_or_branch = rb_funcall(rb_name_or_branch, rb_intern("canonical_name"), 0);
43
+
44
+ if (TYPE(rb_name_or_branch) != T_STRING)
45
+ rb_raise(rb_eTypeError, "Expected #canonical_name to return a String");
46
+
47
+ return git_reference_lookup(branch, repo, StringValueCStr(rb_name_or_branch));
48
+ } else if (TYPE(rb_name_or_branch) == T_STRING) {
49
+ char *branch_name = StringValueCStr(rb_name_or_branch), *ref_name;
50
+ int error;
51
+
52
+ if (strncmp(branch_name, "refs/heads/", strlen("refs/heads/")) == 0 ||
53
+ strncmp(branch_name, "refs/remotes/", strlen("refs/remotes/")) == 0)
54
+ return git_reference_lookup(branch, repo, branch_name);
55
+
56
+ if ((error = git_branch_lookup(branch, repo, branch_name, GIT_BRANCH_LOCAL)) == GIT_OK ||
57
+ error != GIT_ENOTFOUND)
58
+ return error;
59
+
60
+ if ((error = git_branch_lookup(branch, repo, branch_name, GIT_BRANCH_REMOTE)) == GIT_OK ||
61
+ error != GIT_ENOTFOUND)
62
+ return error;
63
+
64
+ ref_name = xmalloc((strlen(branch_name) + strlen("refs/") + 1) * sizeof(char));
65
+ strcpy(ref_name, "refs/");
66
+ strcat(ref_name, branch_name);
67
+
68
+ error = git_reference_lookup(branch, repo, ref_name);
69
+ xfree(ref_name);
70
+
71
+ return error;
72
+ } else {
73
+ rb_raise(rb_eTypeError, "Expecting a String or Rugged::Branch instance");
74
+ }
75
+ }
76
+
77
+ /*
78
+ * call-seq:
79
+ * BranchCollection.new(repo) -> refs
80
+ *
81
+ * Creates and returns a new collection of branches for the given +repo+.
82
+ */
83
+ static VALUE rb_git_branch_collection_initialize(VALUE self, VALUE repo)
84
+ {
85
+ rugged_set_owner(self, repo);
86
+ return self;
87
+ }
88
+
89
+ static git_branch_t parse_branch_type(VALUE rb_filter)
90
+ {
91
+ ID id_filter;
92
+
93
+ Check_Type(rb_filter, T_SYMBOL);
94
+ id_filter = SYM2ID(rb_filter);
95
+
96
+ if (id_filter == rb_intern("local")) {
97
+ return GIT_BRANCH_LOCAL;
98
+ } else if (id_filter == rb_intern("remote")) {
99
+ return GIT_BRANCH_REMOTE;
100
+ } else {
101
+ rb_raise(rb_eTypeError,
102
+ "Invalid branch filter. Expected `:remote`, `:local` or `nil`");
103
+ }
104
+ }
105
+
106
+ /*
107
+ * call-seq:
108
+ * branches.create(name, target, options = {}) -> branch
109
+ *
110
+ * Create a new branch with the given +name+, pointing to the +target+.
111
+ *
112
+ * +name+ needs to be a branch name, not an absolute reference path
113
+ * (e.g. +development+ instead of +refs/heads/development+).
114
+ *
115
+ * +target+ needs to be an existing commit in the given repository.
116
+ *
117
+ * The following options can be passed in the +options+ Hash:
118
+ *
119
+ * :force ::
120
+ * Overwrites the branch with the given +name+, if it already exists,
121
+ * instead of raising an exception.
122
+ *
123
+ * If a branch with the given +name+ already exists and +:force+ is not +true+,
124
+ * an exception will be raised.
125
+ *
126
+ * Returns a Rugged::Branch for the newly created branch.
127
+ */
128
+ static VALUE rb_git_branch_collection_create(int argc, VALUE *argv, VALUE self)
129
+ {
130
+ VALUE rb_repo = rugged_owner(self), rb_name, rb_target, rb_options;
131
+ git_repository *repo;
132
+ git_reference *branch;
133
+ git_commit *target;
134
+ int error, force = 0;
135
+
136
+ rb_scan_args(argc, argv, "20:", &rb_name, &rb_target, &rb_options);
137
+
138
+ rugged_check_repo(rb_repo);
139
+ Data_Get_Struct(rb_repo, git_repository, repo);
140
+
141
+ Check_Type(rb_name, T_STRING);
142
+ Check_Type(rb_target, T_STRING);
143
+
144
+ if (!NIL_P(rb_options)) {
145
+ force = RTEST(rb_hash_aref(rb_options, CSTR2SYM("force")));
146
+ }
147
+
148
+ target = (git_commit *)rugged_object_get(repo, rb_target, GIT_OBJ_COMMIT);
149
+
150
+ error = git_branch_create(&branch, repo, StringValueCStr(rb_name), target, force);
151
+
152
+ git_commit_free(target);
153
+
154
+ rugged_exception_check(error);
155
+
156
+ return rugged_branch_new(rb_repo, branch);
157
+ }
158
+
159
+ /*
160
+ * call-seq:
161
+ * branches[name] -> branch
162
+ *
163
+ * Return the branch with the given +name+.
164
+ *
165
+ * Branches can be looked up by their relative (+development+) or absolute
166
+ * (+refs/heads/development+) branch name.
167
+ *
168
+ * If a local branch and a remote branch both share the same short name
169
+ * (e.g. +refs/heads/origin/master+ and +refs/remotes/origin/master+),
170
+ * passing +origin/master+ as the +name+ will return the local branch.
171
+ * You can explicitly request the local branch by passing
172
+ * +heads/origin/master+, or the remote branch through +remotes/origin/master+.
173
+ *
174
+ * Returns the looked up branch, or +nil+ if the branch doesn't exist.
175
+ */
176
+ static VALUE rb_git_branch_collection_aref(VALUE self, VALUE rb_name) {
177
+ git_reference *branch;
178
+ git_repository *repo;
179
+
180
+ VALUE rb_repo = rugged_owner(self);
181
+ int error;
182
+
183
+ rugged_check_repo(rb_repo);
184
+ Data_Get_Struct(rb_repo, git_repository, repo);
185
+
186
+ Check_Type(rb_name, T_STRING);
187
+
188
+ error = rugged_branch_lookup(&branch, repo, rb_name);
189
+ if (error == GIT_ENOTFOUND)
190
+ return Qnil;
191
+
192
+ rugged_exception_check(error);
193
+ return rugged_branch_new(rb_repo, branch);
194
+ }
195
+
196
+ static VALUE each_branch(int argc, VALUE *argv, VALUE self, int branch_names_only)
197
+ {
198
+ VALUE rb_repo = rugged_owner(self), rb_filter;
199
+ git_repository *repo;
200
+ git_branch_iterator *iter;
201
+ int error, exception = 0;
202
+ git_branch_t filter = (GIT_BRANCH_LOCAL | GIT_BRANCH_REMOTE), branch_type;
203
+
204
+ rb_scan_args(argc, argv, "01", &rb_filter);
205
+
206
+ if (!rb_block_given_p()) {
207
+ VALUE symbol = branch_names_only ? CSTR2SYM("each_name") : CSTR2SYM("each");
208
+ return rb_funcall(self, rb_intern("to_enum"), 2, symbol, rb_filter);
209
+ }
210
+
211
+ rugged_check_repo(rb_repo);
212
+
213
+ if (!NIL_P(rb_filter))
214
+ filter = parse_branch_type(rb_filter);
215
+
216
+ Data_Get_Struct(rb_repo, git_repository, repo);
217
+
218
+ error = git_branch_iterator_new(&iter, repo, filter);
219
+ rugged_exception_check(error);
220
+
221
+ if (branch_names_only) {
222
+ git_reference *branch;
223
+ while (!exception && (error = git_branch_next(&branch, &branch_type, iter)) == GIT_OK) {
224
+ rb_protect(rb_yield, rb_str_new_utf8(git_reference_shorthand(branch)), &exception);
225
+ }
226
+ } else {
227
+ git_reference *branch;
228
+ while (!exception && (error = git_branch_next(&branch, &branch_type, iter)) == GIT_OK) {
229
+ rb_protect(rb_yield, rugged_branch_new(rb_repo, branch), &exception);
230
+ }
231
+ }
232
+
233
+ git_branch_iterator_free(iter);
234
+
235
+ if (exception)
236
+ rb_jump_tag(exception);
237
+
238
+ if (error != GIT_ITEROVER)
239
+ rugged_exception_check(error);
240
+
241
+ return Qnil;
242
+ }
243
+
244
+ /*
245
+ * call-seq:
246
+ * branches.each([filter]) { |branch| block }
247
+ * branches.each([filter]) -> enumerator
248
+ *
249
+ * Iterate through the branches in the collection. Iteration can be
250
+ * optionally filtered to yield only +:local+ or +:remote+ branches.
251
+ *
252
+ * The given block will be called once with a +Rugged::Branch+ object
253
+ * for each branch in the repository. If no block is given, an enumerator
254
+ * will be returned.
255
+ */
256
+ static VALUE rb_git_branch_collection_each(int argc, VALUE *argv, VALUE self)
257
+ {
258
+ return each_branch(argc, argv, self, 0);
259
+ }
260
+
261
+ /*
262
+ * call-seq:
263
+ * branches.each_name([filter]) { |branch_name| block }
264
+ * branches.each_name([filter]) -> enumerator
265
+ *
266
+ * Iterate through the names of the branches in the collection. Iteration can be
267
+ * optionally filtered to yield only +:local+ or +:remote+ branches.
268
+ *
269
+ * The given block will be called once with the name of each branch as a +String+.
270
+ * If no block is given, an enumerator will be returned.
271
+ */
272
+ static VALUE rb_git_branch_collection_each_name(int argc, VALUE *argv, VALUE self)
273
+ {
274
+ return each_branch(argc, argv, self, 1);
275
+ }
276
+
277
+ /*
278
+ * call-seq:
279
+ * branches.delete(branch) -> nil
280
+ * branches.delete(name) -> nil
281
+ *
282
+ * Delete the specified branch.
283
+ *
284
+ * If a Rugged::Branch object was passed, the object will become
285
+ * invalidated and won't be able to be used for any other operations.
286
+ */
287
+ static VALUE rb_git_branch_collection_delete(VALUE self, VALUE rb_name_or_branch)
288
+ {
289
+ git_reference *branch;
290
+ git_repository *repo;
291
+
292
+ VALUE rb_repo = rugged_owner(self);
293
+ int error;
294
+
295
+ rugged_check_repo(rb_repo);
296
+ Data_Get_Struct(rb_repo, git_repository, repo);
297
+
298
+ error = rugged_branch_lookup(&branch, repo, rb_name_or_branch);
299
+ rugged_exception_check(error);
300
+
301
+ error = git_branch_delete(branch);
302
+ git_reference_free(branch);
303
+ rugged_exception_check(error);
304
+
305
+ return Qnil;
306
+ }
307
+
308
+ /*
309
+ * call-seq:
310
+ * branch.move(old_name, new_name, options = {}) -> new_branch
311
+ * branch.move(branch, new_name, options = {}) -> new_branch
312
+ * branch.rename(old_name, new_name, options = {}) -> new_branch
313
+ * branch.rename(branch, new_name, options = {}) -> new_branch
314
+ *
315
+ * Rename a branch to +new_name+.
316
+ *
317
+ * +new_name+ needs to be a branch name, not an absolute reference path
318
+ * (e.g. +development+ instead of +refs/heads/development+).
319
+ *
320
+ * The following options can be passed in the +options+ Hash:
321
+ *
322
+ * :force ::
323
+ * Overwrites the branch with the given +name+, if it already exists,
324
+ * instead of raising an exception.
325
+ *
326
+ * If a branch with the given +new_name+ already exists and +:force+ is not +true+,
327
+ * an exception will be raised.
328
+ *
329
+ * A new Rugged::Branch object for the renamed branch will be returned.
330
+ *
331
+ */
332
+ static VALUE rb_git_branch_collection_move(int argc, VALUE *argv, VALUE self)
333
+ {
334
+ VALUE rb_repo = rugged_owner(self), rb_name_or_branch, rb_new_branch_name, rb_options;
335
+ git_reference *old_branch = NULL, *new_branch = NULL;
336
+ git_repository *repo;
337
+ int error, force = 0;
338
+
339
+ rb_scan_args(argc, argv, "20:", &rb_name_or_branch, &rb_new_branch_name, &rb_options);
340
+ Check_Type(rb_new_branch_name, T_STRING);
341
+
342
+ rugged_check_repo(rb_repo);
343
+ Data_Get_Struct(rb_repo, git_repository, repo);
344
+
345
+ error = rugged_branch_lookup(&old_branch, repo, rb_name_or_branch);
346
+ rugged_exception_check(error);
347
+
348
+ if (!NIL_P(rb_options)) {
349
+ force = RTEST(rb_hash_aref(rb_options, CSTR2SYM("force")));
350
+ }
351
+
352
+ error = git_branch_move(&new_branch, old_branch, StringValueCStr(rb_new_branch_name), force);
353
+
354
+ git_reference_free(old_branch);
355
+
356
+ rugged_exception_check(error);
357
+
358
+ return rugged_branch_new(rugged_owner(self), new_branch);
359
+ }
360
+
361
+ /*
362
+ * call-seq:
363
+ * branches.exist?(name) -> true or false
364
+ * branches.exists?(name) -> true or false
365
+ *
366
+ * Check if a branch exists with the given +name+.
367
+ */
368
+ static VALUE rb_git_branch_collection_exist_p(VALUE self, VALUE rb_name)
369
+ {
370
+ VALUE rb_repo = rugged_owner(self);
371
+ git_repository *repo;
372
+ git_reference *branch;
373
+ int error;
374
+
375
+ Check_Type(rb_name, T_STRING);
376
+ Data_Get_Struct(rb_repo, git_repository, repo);
377
+
378
+ error = rugged_branch_lookup(&branch, repo, rb_name);
379
+ git_reference_free(branch);
380
+
381
+ if (error == GIT_ENOTFOUND)
382
+ return Qfalse;
383
+ else
384
+ rugged_exception_check(error);
385
+
386
+ return Qtrue;
387
+ }
388
+
389
+ void Init_rugged_branch_collection(void)
390
+ {
391
+ rb_cRuggedBranchCollection = rb_define_class_under(rb_mRugged, "BranchCollection", rb_cObject);
392
+ rb_include_module(rb_cRuggedBranchCollection, rb_mEnumerable);
393
+
394
+ rb_define_method(rb_cRuggedBranchCollection, "initialize", rb_git_branch_collection_initialize, 1);
395
+
396
+ rb_define_method(rb_cRuggedBranchCollection, "[]", rb_git_branch_collection_aref, 1);
397
+ rb_define_method(rb_cRuggedBranchCollection, "create", rb_git_branch_collection_create, -1);
398
+
399
+ rb_define_method(rb_cRuggedBranchCollection, "each", rb_git_branch_collection_each, -1);
400
+ rb_define_method(rb_cRuggedBranchCollection, "each_name", rb_git_branch_collection_each_name, -1);
401
+
402
+ rb_define_method(rb_cRuggedBranchCollection, "exist?", rb_git_branch_collection_exist_p, 1);
403
+ rb_define_method(rb_cRuggedBranchCollection, "exists?", rb_git_branch_collection_exist_p, 1);
404
+
405
+ rb_define_method(rb_cRuggedBranchCollection, "move", rb_git_branch_collection_move, -1);
406
+ rb_define_method(rb_cRuggedBranchCollection, "rename", rb_git_branch_collection_move, -1);
407
+ rb_define_method(rb_cRuggedBranchCollection, "delete", rb_git_branch_collection_delete, 1);
408
+ }