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,185 @@
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
+ #ifndef __H_RUGGED_BINDINGS__
26
+ #define __H_RUGGED_BINDINGS__
27
+
28
+ // tell rbx not to use it's caching compat layer
29
+ // by doing this we're making a promize to RBX that
30
+ // we'll never modify the pointers we get back from RSTRING_PTR
31
+ #define RSTRING_NOT_MODIFIED
32
+
33
+ #include <ruby.h>
34
+ #ifndef HAVE_RUBY_ENCODING_H
35
+ #error "Rugged requires Ruby 1.9+ to build"
36
+ #else
37
+ #include <ruby/encoding.h>
38
+ #endif
39
+
40
+ #include <assert.h>
41
+ #include <git2.h>
42
+ #include <git2/odb_backend.h>
43
+
44
+ #define rb_str_new_utf8(str) rb_enc_str_new(str, strlen(str), rb_utf8_encoding())
45
+ #define CSTR2SYM(s) (ID2SYM(rb_intern((s))))
46
+
47
+ /*
48
+ * Initialization functions
49
+ */
50
+ void Init_rugged_object(void);
51
+ void Init_rugged_branch(void);
52
+ void Init_rugged_branch_collection(void);
53
+ void Init_rugged_commit(void);
54
+ void Init_rugged_tree(void);
55
+ void Init_rugged_tag(void);
56
+ void Init_rugged_tag_collection(void);
57
+ void Init_rugged_blob(void);
58
+ void Init_rugged_index(void);
59
+ void Init_rugged_repo(void);
60
+ void Init_rugged_revwalk(void);
61
+ void Init_rugged_reference(void);
62
+ void Init_rugged_reference_collection(void);
63
+ void Init_rugged_config(void);
64
+ void Init_rugged_remote(void);
65
+ void Init_rugged_remote_collection(void);
66
+ void Init_rugged_notes(void);
67
+ void Init_rugged_settings(void);
68
+ void Init_rugged_submodule(void);
69
+ void Init_rugged_submodule_collection(void);
70
+ void Init_rugged_diff(void);
71
+ void Init_rugged_patch(void);
72
+ void Init_rugged_diff_delta(void);
73
+ void Init_rugged_diff_hunk(void);
74
+ void Init_rugged_diff_line(void);
75
+ void Init_rugged_blame(void);
76
+ void Init_rugged_cred(void);
77
+ void Init_rugged_backend(void);
78
+
79
+ VALUE rb_git_object_init(git_otype type, int argc, VALUE *argv, VALUE self);
80
+
81
+ VALUE rugged_raw_read(git_repository *repo, const git_oid *oid);
82
+
83
+ VALUE rugged_signature_new(const git_signature *sig, const char *encoding_name);
84
+
85
+ VALUE rugged_repo_new(VALUE klass, git_repository *repo);
86
+ VALUE rugged_index_new(VALUE klass, VALUE owner, git_index *index);
87
+ VALUE rugged_config_new(VALUE klass, VALUE owner, git_config *cfg);
88
+ VALUE rugged_object_new(VALUE owner, git_object *object);
89
+ VALUE rugged_object_rev_parse(VALUE rb_repo, VALUE rb_spec, int as_obj);
90
+ VALUE rugged_ref_new(VALUE klass, VALUE owner, git_reference *ref);
91
+ VALUE rugged_diff_new(VALUE klass, VALUE owner, git_diff *diff);
92
+ VALUE rugged_patch_new(VALUE owner, git_patch *patch);
93
+ VALUE rugged_diff_delta_new(VALUE owner, const git_diff_delta *delta);
94
+ VALUE rugged_diff_hunk_new(VALUE owner, size_t hunk_idx, const git_diff_hunk *hunk, size_t lines_in_hunk);
95
+ VALUE rugged_diff_line_new(const git_diff_line *line);
96
+ VALUE rugged_remote_new(VALUE owner, git_remote *remote);
97
+ VALUE rb_git_delta_file_fromC(const git_diff_file *file);
98
+
99
+ void rugged_parse_diff_options(git_diff_options *opts, VALUE rb_options);
100
+ void rugged_parse_merge_options(git_merge_options *opts, VALUE rb_options);
101
+
102
+ void rugged_cred_extract(git_cred **cred, int allowed_types, VALUE rb_credential);
103
+
104
+ VALUE rugged_otype_new(git_otype t);
105
+ git_otype rugged_otype_get(VALUE rb_type);
106
+
107
+ git_signature *rugged_signature_get(VALUE rb_person, git_repository *repo);
108
+ git_object *rugged_object_get(git_repository *repo, VALUE object_value, git_otype type);
109
+ int rugged_oid_get(git_oid *oid, git_repository *repo, VALUE p);
110
+
111
+ void rugged_rb_ary_to_strarray(VALUE rb_array, git_strarray *str_array);
112
+ VALUE rugged_strarray_to_rb_ary(git_strarray *str_array);
113
+
114
+ static inline void rugged_set_owner(VALUE object, VALUE owner)
115
+ {
116
+ rb_iv_set(object, "@owner", owner);
117
+ }
118
+
119
+ static inline VALUE rugged_owner(VALUE object)
120
+ {
121
+ return rb_iv_get(object, "@owner");
122
+ }
123
+
124
+ extern void rugged_exception_raise(void);
125
+
126
+ static inline void rugged_exception_check(int errorcode)
127
+ {
128
+ if (errorcode < 0)
129
+ rugged_exception_raise();
130
+ }
131
+
132
+ static inline int rugged_parse_bool(VALUE boolean)
133
+ {
134
+ if (TYPE(boolean) != T_TRUE && TYPE(boolean) != T_FALSE)
135
+ rb_raise(rb_eTypeError, "Expected boolean value");
136
+
137
+ return boolean ? 1 : 0;
138
+ }
139
+
140
+ extern VALUE rb_cRuggedRepo;
141
+
142
+ VALUE rugged__block_yield_splat(VALUE args);
143
+
144
+ struct rugged_cb_payload
145
+ {
146
+ VALUE rb_data;
147
+ int exception;
148
+ };
149
+
150
+ struct rugged_remote_cb_payload
151
+ {
152
+ VALUE progress;
153
+ VALUE completion;
154
+ VALUE transfer_progress;
155
+ VALUE update_tips;
156
+ VALUE credentials;
157
+ VALUE result;
158
+ int exception;
159
+ };
160
+
161
+ void rugged_remote_init_callbacks_and_payload_from_options(
162
+ VALUE rb_options,
163
+ git_remote_callbacks *callbacks,
164
+ struct rugged_remote_cb_payload *payload);
165
+
166
+ static inline void rugged_check_repo(VALUE rb_repo)
167
+ {
168
+ if (!rb_obj_is_kind_of(rb_repo, rb_cRuggedRepo))
169
+ rb_raise(rb_eTypeError, "Expecting a Rugged Repository");
170
+ }
171
+
172
+ static inline VALUE rugged_create_oid(const git_oid *oid)
173
+ {
174
+ char out[40];
175
+ git_oid_fmt(out, oid);
176
+ return rb_str_new(out, 40);
177
+ }
178
+
179
+
180
+ typedef struct _rugged_backend {
181
+ int (* odb_backend)(git_odb_backend **backend_out, struct _rugged_backend *backend, const char* path);
182
+ int (* refdb_backend)(git_refdb_backend **backend_out, struct _rugged_backend *backend, const char* path);
183
+ } rugged_backend;
184
+
185
+ #endif
@@ -0,0 +1,34 @@
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
+
29
+ VALUE rb_cRuggedBackend;
30
+
31
+ void Init_rugged_backend(void)
32
+ {
33
+ rb_cRuggedBackend = rb_define_class_under(rb_mRugged, "Backend", rb_cObject);
34
+ }
@@ -0,0 +1,292 @@
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
+ VALUE rb_cRuggedBlame;
29
+
30
+ static VALUE rb_git_blame_hunk_fromC(const git_blame_hunk *hunk)
31
+ {
32
+ VALUE rb_hunk;
33
+ if (!hunk) {
34
+ return Qnil;
35
+ }
36
+
37
+ rb_hunk = rb_hash_new();
38
+ rb_hash_aset(rb_hunk, CSTR2SYM("lines_in_hunk"), UINT2NUM(hunk->lines_in_hunk));
39
+
40
+ rb_hash_aset(rb_hunk, CSTR2SYM("final_commit_id"), rugged_create_oid(&(hunk->final_commit_id)));
41
+ rb_hash_aset(rb_hunk, CSTR2SYM("final_start_line_number"), UINT2NUM(hunk->final_start_line_number));
42
+ rb_hash_aset(rb_hunk, CSTR2SYM("final_signature"), hunk->final_signature ? rugged_signature_new(hunk->final_signature, NULL) : Qnil);
43
+
44
+ rb_hash_aset(rb_hunk, CSTR2SYM("orig_commit_id"), rugged_create_oid(&(hunk->orig_commit_id)));
45
+ rb_hash_aset(rb_hunk, CSTR2SYM("orig_path"), hunk->orig_path ? rb_str_new2(hunk->orig_path) : Qnil);
46
+ rb_hash_aset(rb_hunk, CSTR2SYM("orig_start_line_number"), UINT2NUM(hunk->orig_start_line_number));
47
+ rb_hash_aset(rb_hunk, CSTR2SYM("orig_signature"), hunk->orig_signature ? rugged_signature_new(hunk->orig_signature, NULL) : Qnil);
48
+
49
+ rb_hash_aset(rb_hunk, CSTR2SYM("boundary"), hunk->boundary ? Qtrue : Qfalse);
50
+
51
+ return rb_hunk;
52
+ }
53
+
54
+ static void rugged_parse_blame_options(git_blame_options *opts, git_repository *repo, VALUE rb_options)
55
+ {
56
+ if (!NIL_P(rb_options)) {
57
+ VALUE rb_value;
58
+ Check_Type(rb_options, T_HASH);
59
+
60
+ rb_value = rb_hash_aref(rb_options, CSTR2SYM("min_line"));
61
+ if (!NIL_P(rb_value)) {
62
+ Check_Type(rb_value, T_FIXNUM);
63
+ opts->min_line = FIX2UINT(rb_value);
64
+ }
65
+
66
+ rb_value = rb_hash_aref(rb_options, CSTR2SYM("max_line"));
67
+ if (!NIL_P(rb_value)) {
68
+ Check_Type(rb_value, T_FIXNUM);
69
+ opts->max_line = FIX2UINT(rb_value);
70
+ }
71
+
72
+ rb_value = rb_hash_aref(rb_options, CSTR2SYM("newest_commit"));
73
+ if (!NIL_P(rb_value)) {
74
+ int error = rugged_oid_get(&opts->newest_commit, repo, rb_value);
75
+ rugged_exception_check(error);
76
+ }
77
+
78
+ rb_value = rb_hash_aref(rb_options, CSTR2SYM("oldest_commit"));
79
+ if (!NIL_P(rb_value)) {
80
+ int error = rugged_oid_get(&opts->oldest_commit, repo, rb_value);
81
+ rugged_exception_check(error);
82
+ }
83
+
84
+ if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("track_copies_same_file")))) {
85
+ opts->flags |= GIT_BLAME_TRACK_COPIES_SAME_FILE;
86
+ }
87
+
88
+ if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("track_copies_same_commit_moves")))) {
89
+ opts->flags |= GIT_BLAME_TRACK_COPIES_SAME_COMMIT_MOVES;
90
+ }
91
+
92
+ if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("track_copies_same_commit_copies")))) {
93
+ opts->flags |= GIT_BLAME_TRACK_COPIES_SAME_COMMIT_COPIES;
94
+ }
95
+
96
+ if (RTEST(rb_hash_aref(rb_options, CSTR2SYM("track_copies_any_commit_copies")))) {
97
+ opts->flags |= GIT_BLAME_TRACK_COPIES_ANY_COMMIT_COPIES;
98
+ }
99
+ }
100
+ }
101
+
102
+ /*
103
+ * call-seq:
104
+ * Blame.new(repo, path, options = {}) -> blame
105
+ *
106
+ * Get blame data for the file at +path+ in +repo+.
107
+ *
108
+ * The following options can be passed in the +options+ Hash:
109
+ *
110
+ * :newest_commit ::
111
+ * The ID of the newest commit to consider in the blame. Defaults to +HEAD+.
112
+ * This can either be a Rugged::Object instance, or a full or abbreviated
113
+ * SHA1 id.
114
+ *
115
+ * :oldest_commit ::
116
+ * The id of the oldest commit to consider. Defaults to the first commit
117
+ * encountered with a NULL parent. This can either be a Rugged::Object
118
+ * instance, or a full or abbreviated SHA1 id.
119
+ *
120
+ * :min_line ::
121
+ * The first line in the file to blame. Line numbers start with 1.
122
+ * Defaults to +1+.
123
+ *
124
+ * :max_line ::
125
+ * The last line in the file to blame. Defaults to the last line in
126
+ * the file.
127
+ *
128
+ * :track_copies_same_file
129
+ * If this value is +true+, lines that have moved within a file will be
130
+ * tracked (like `git blame -M`).
131
+ *
132
+ * :track_copies_same_commit_moves
133
+ * If this value is +true+, lines that have moved across files in the same
134
+ * commit will be tracked (like `git blame -C`).
135
+ *
136
+ * :track_copies_same_commit_copies
137
+ * If this value is +true+, lines that have been copied from another file
138
+ * that exists in the same commit will be tracked (like `git blame -CC`).
139
+ *
140
+ * :track_copies_any_commit_copies
141
+ * If this value is +true+, lines that have been copied from another file
142
+ * that exists in *any* commit will be tracked (like `git blame -CCC`).
143
+ *
144
+ */
145
+ static VALUE rb_git_blame_new(int argc, VALUE *argv, VALUE klass)
146
+ {
147
+ VALUE rb_repo, rb_path, rb_options;
148
+ git_repository *repo;
149
+ git_blame *blame;
150
+ git_blame_options opts = GIT_BLAME_OPTIONS_INIT;
151
+
152
+ rb_scan_args(argc, argv, "20:", &rb_repo, &rb_path, &rb_options);
153
+
154
+ rugged_check_repo(rb_repo);
155
+ Data_Get_Struct(rb_repo, git_repository, repo);
156
+
157
+ Check_Type(rb_path, T_STRING);
158
+
159
+ rugged_parse_blame_options(&opts, repo, rb_options);
160
+
161
+ rugged_exception_check(git_blame_file(
162
+ &blame, repo, StringValueCStr(rb_path), &opts
163
+ ));
164
+
165
+ return Data_Wrap_Struct(klass, NULL, &git_blame_free, blame);
166
+ }
167
+
168
+ /*
169
+ * call-seq:
170
+ * blame.for_line(line_no) -> hunk
171
+ *
172
+ * Returns the blame hunk data for the given +line_no+ in +blame+.
173
+ * Line number counting starts with +1+.
174
+ */
175
+ static VALUE rb_git_blame_for_line(VALUE self, VALUE rb_line_no)
176
+ {
177
+ git_blame *blame;
178
+ int line_no;
179
+
180
+ Data_Get_Struct(self, git_blame, blame);
181
+ Check_Type(rb_line_no, T_FIXNUM);
182
+
183
+ line_no = NUM2INT(rb_line_no);
184
+
185
+ if (line_no < 0) {
186
+ rb_raise(rb_eArgError, "line number can't be negative");
187
+ }
188
+
189
+ return rb_git_blame_hunk_fromC(
190
+ git_blame_get_hunk_byline(blame, (uint32_t)line_no)
191
+ );
192
+ }
193
+
194
+ /*
195
+ * call-seq:
196
+ * blame.count -> count
197
+ * blame.size -> count
198
+ *
199
+ * Returns the total +count+ of blame hunks in +blame+.
200
+ */
201
+ static VALUE rb_git_blame_count(VALUE self)
202
+ {
203
+ git_blame *blame;
204
+ Data_Get_Struct(self, git_blame, blame);
205
+ return UINT2NUM(git_blame_get_hunk_count(blame));
206
+ }
207
+
208
+ /*
209
+ * call-seq:
210
+ * blame[index] -> hunk
211
+ *
212
+ * Returns the blame hunk data at the given +index+ in +blame+.
213
+ *
214
+ * Negative indices count backward from the end of the blame hunks (-1 is the last
215
+ * element).
216
+ *
217
+ * Returns +nil+ if no blame hunk exists at the given +index+.
218
+ */
219
+ static VALUE rb_git_blame_get_by_index(VALUE self, VALUE rb_index)
220
+ {
221
+ git_blame *blame;
222
+ int index;
223
+ uint32_t blame_count;
224
+
225
+ Data_Get_Struct(self, git_blame, blame);
226
+ Check_Type(rb_index, T_FIXNUM);
227
+
228
+ index = NUM2INT(rb_index);
229
+ blame_count = git_blame_get_hunk_count(blame);
230
+
231
+ if (index < 0) {
232
+ if ((uint32_t)(-index) > blame_count) {
233
+ return Qnil;
234
+ }
235
+
236
+ return rb_git_blame_hunk_fromC(
237
+ git_blame_get_hunk_byindex(blame, (uint32_t)(blame_count + index))
238
+ );
239
+ }
240
+
241
+ if ((uint32_t)index > blame_count)
242
+ return Qnil;
243
+
244
+ return rb_git_blame_hunk_fromC(
245
+ git_blame_get_hunk_byindex(blame, (uint32_t)index)
246
+ );
247
+ }
248
+
249
+ /*
250
+ * call-seq:
251
+ * blame.each { |hunk| ... } -> blame
252
+ * blame.each -> enumerator
253
+ *
254
+ * If given a block, yields each +hunk+ that is part of +blame+.
255
+ * If no block is given, an enumerator will be returned.
256
+ */
257
+ static VALUE rb_git_blame_each(VALUE self)
258
+ {
259
+ git_blame *blame;
260
+ uint32_t i, blame_count;
261
+
262
+ if (!rb_block_given_p()) {
263
+ return rb_funcall(self, rb_intern("to_enum"), 1, CSTR2SYM("each"), self);
264
+ }
265
+
266
+ Data_Get_Struct(self, git_blame, blame);
267
+
268
+ blame_count = git_blame_get_hunk_count(blame);
269
+ for (i = 0; i < blame_count; ++i) {
270
+ rb_yield(rb_git_blame_hunk_fromC(
271
+ git_blame_get_hunk_byindex(blame, i)
272
+ ));
273
+ }
274
+
275
+ return self;
276
+ }
277
+
278
+ void Init_rugged_blame(void)
279
+ {
280
+ rb_cRuggedBlame = rb_define_class_under(rb_mRugged, "Blame", rb_cObject);
281
+ rb_include_module(rb_cRuggedBlame, rb_mEnumerable);
282
+
283
+ rb_define_singleton_method(rb_cRuggedBlame, "new", rb_git_blame_new, -1);
284
+
285
+ rb_define_method(rb_cRuggedBlame, "[]", rb_git_blame_get_by_index, 1);
286
+ rb_define_method(rb_cRuggedBlame, "for_line", rb_git_blame_for_line, 1);
287
+
288
+ rb_define_method(rb_cRuggedBlame, "count", rb_git_blame_count, 0);
289
+ rb_define_method(rb_cRuggedBlame, "size", rb_git_blame_count, 0);
290
+
291
+ rb_define_method(rb_cRuggedBlame, "each", rb_git_blame_each, 0);
292
+ }