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,495 @@
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_cRuggedObject;
29
+ VALUE rb_cRuggedWalker;
30
+
31
+ static void rb_git_walk__free(git_revwalk *walk)
32
+ {
33
+ git_revwalk_free(walk);
34
+ }
35
+
36
+ VALUE rugged_walker_new(VALUE klass, VALUE owner, git_revwalk *walk)
37
+ {
38
+ VALUE rb_walk = Data_Wrap_Struct(klass, NULL, &rb_git_walk__free, walk);
39
+ rugged_set_owner(rb_walk, owner);
40
+ return rb_walk;
41
+ }
42
+
43
+ static void push_commit_oid(git_revwalk *walk, const git_oid *oid, int hide)
44
+ {
45
+ int error;
46
+ if (hide) error = git_revwalk_hide(walk, oid);
47
+ else error = git_revwalk_push(walk, oid);
48
+ rugged_exception_check(error);
49
+ }
50
+
51
+ static void push_commit_ref(git_revwalk *walk, const char *ref, int hide)
52
+ {
53
+ int error;
54
+ if (hide) error = git_revwalk_hide_ref(walk, ref);
55
+ else error = git_revwalk_push_ref(walk, ref);
56
+ rugged_exception_check(error);
57
+ }
58
+
59
+ static void push_commit_1(git_revwalk *walk, VALUE rb_commit, int hide)
60
+ {
61
+ if (rb_obj_is_kind_of(rb_commit, rb_cRuggedObject)) {
62
+ git_object *object;
63
+ Data_Get_Struct(rb_commit, git_object, object);
64
+
65
+ push_commit_oid(walk, git_object_id(object), hide);
66
+ return;
67
+ }
68
+
69
+ Check_Type(rb_commit, T_STRING);
70
+
71
+ if (RSTRING_LEN(rb_commit) == 40) {
72
+ git_oid commit_oid;
73
+ if (git_oid_fromstr(&commit_oid, RSTRING_PTR(rb_commit)) == 0) {
74
+ push_commit_oid(walk, &commit_oid, hide);
75
+ return;
76
+ }
77
+ }
78
+
79
+ push_commit_ref(walk, StringValueCStr(rb_commit), hide);
80
+ }
81
+
82
+ static void push_commit(git_revwalk *walk, VALUE rb_commit, int hide)
83
+ {
84
+ if (rb_type(rb_commit) == T_ARRAY) {
85
+ long i;
86
+ for (i = 0; i < RARRAY_LEN(rb_commit); ++i)
87
+ push_commit_1(walk, rb_ary_entry(rb_commit, i), hide);
88
+
89
+ return;
90
+ }
91
+
92
+ push_commit_1(walk, rb_commit, hide);
93
+ }
94
+
95
+ /*
96
+ * call-seq:
97
+ * Walker.new(repository) -> walker
98
+ *
99
+ * Create a new +Walker+ instance able to walk commits found
100
+ * in +repository+, which is a <tt>Rugged::Repository</tt> instance.
101
+ */
102
+ static VALUE rb_git_walker_new(VALUE klass, VALUE rb_repo)
103
+ {
104
+ git_repository *repo;
105
+ git_revwalk *walk;
106
+ int error;
107
+
108
+ Data_Get_Struct(rb_repo, git_repository, repo);
109
+
110
+ error = git_revwalk_new(&walk, repo);
111
+ rugged_exception_check(error);
112
+
113
+ return rugged_walker_new(klass, rb_repo, walk);;
114
+ }
115
+
116
+ /*
117
+ * call-seq:
118
+ * walker.push(commit) -> nil
119
+ *
120
+ * Push one new +commit+ to start the walk from. +commit+ must be a
121
+ * +String+ with the OID of a commit in the repository, or a <tt>Rugged::Commit</tt>
122
+ * instance.
123
+ *
124
+ * More than one commit may be pushed to the walker (to walk several
125
+ * branches simulataneously).
126
+ *
127
+ * Duplicate pushed commits will be ignored; at least one commit must have been
128
+ * pushed as a starting point before the walk can begin.
129
+ *
130
+ * walker.push("92b22bbcb37caf4f6f53d30292169e84f5e4283b")
131
+ */
132
+ static VALUE rb_git_walker_push(VALUE self, VALUE rb_commit)
133
+ {
134
+ git_revwalk *walk;
135
+ Data_Get_Struct(self, git_revwalk, walk);
136
+ push_commit(walk, rb_commit, 0);
137
+ return Qnil;
138
+ }
139
+
140
+ static VALUE rb_git_walker_push_range(VALUE self, VALUE range)
141
+ {
142
+ git_revwalk *walk;
143
+ Data_Get_Struct(self, git_revwalk, walk);
144
+ rugged_exception_check(git_revwalk_push_range(walk, StringValueCStr(range)));
145
+ return Qnil;
146
+ }
147
+
148
+ /*
149
+ * call-seq:
150
+ * walker.hide(commit) -> nil
151
+ *
152
+ * Hide the given +commit+ (and all its parents) from the
153
+ * output in the revision walk.
154
+ */
155
+ static VALUE rb_git_walker_hide(VALUE self, VALUE rb_commit)
156
+ {
157
+ git_revwalk *walk;
158
+ Data_Get_Struct(self, git_revwalk, walk);
159
+ push_commit(walk, rb_commit, 1);
160
+ return Qnil;
161
+ }
162
+
163
+ /*
164
+ * call-seq:
165
+ * walker.sorting(sort_mode) -> nil
166
+ *
167
+ * Change the sorting mode for the revision walk.
168
+ *
169
+ * This will cause +walker+ to be reset.
170
+ */
171
+ static VALUE rb_git_walker_sorting(VALUE self, VALUE ruby_sort_mode)
172
+ {
173
+ git_revwalk *walk;
174
+ Data_Get_Struct(self, git_revwalk, walk);
175
+ git_revwalk_sorting(walk, FIX2INT(ruby_sort_mode));
176
+ return Qnil;
177
+ }
178
+
179
+ /*
180
+ * call-seq:
181
+ * walker.simplify_first_parent() -> nil
182
+ *
183
+ * Simplify the walk to the first parent of each commit.
184
+ */
185
+ static VALUE rb_git_walker_simplify_first_parent(VALUE self)
186
+ {
187
+ git_revwalk *walk;
188
+ Data_Get_Struct(self, git_revwalk, walk);
189
+ git_revwalk_simplify_first_parent(walk);
190
+ return Qnil;
191
+ }
192
+
193
+ /*
194
+ * call-seq:
195
+ * walker.reset -> nil
196
+ *
197
+ * Remove all pushed and hidden commits and reset the +walker+
198
+ * back into a blank state.
199
+ */
200
+ static VALUE rb_git_walker_reset(VALUE self)
201
+ {
202
+ git_revwalk *walk;
203
+ Data_Get_Struct(self, git_revwalk, walk);
204
+ git_revwalk_reset(walk);
205
+ return Qnil;
206
+ }
207
+
208
+ struct walk_options {
209
+ VALUE rb_owner;
210
+ VALUE rb_options;
211
+
212
+ git_repository *repo;
213
+ git_revwalk *walk;
214
+ int oid_only;
215
+ uint64_t offset, limit;
216
+ };
217
+
218
+ static void load_walk_limits(struct walk_options *w, VALUE rb_options)
219
+ {
220
+ VALUE rb_value = rb_hash_lookup(rb_options, CSTR2SYM("offset"));
221
+ if (!NIL_P(rb_value)) {
222
+ Check_Type(rb_value, T_FIXNUM);
223
+ w->offset = FIX2ULONG(rb_value);
224
+ }
225
+
226
+ rb_value = rb_hash_lookup(rb_options, CSTR2SYM("limit"));
227
+ if (!NIL_P(rb_value)) {
228
+ Check_Type(rb_value, T_FIXNUM);
229
+ w->limit = FIX2ULONG(rb_value);
230
+ }
231
+ }
232
+
233
+ static VALUE load_all_options(VALUE _payload)
234
+ {
235
+ struct walk_options *w = (struct walk_options *)_payload;
236
+ VALUE rb_options = w->rb_options;
237
+ VALUE rb_show, rb_hide, rb_sort, rb_simp, rb_oid_only;
238
+
239
+ load_walk_limits(w, rb_options);
240
+
241
+ rb_sort = rb_hash_lookup(rb_options, CSTR2SYM("sort"));
242
+ if (!NIL_P(rb_sort)) {
243
+ Check_Type(rb_sort, T_FIXNUM);
244
+ git_revwalk_sorting(w->walk, FIX2INT(rb_sort));
245
+ }
246
+
247
+ rb_show = rb_hash_lookup(rb_options, CSTR2SYM("show"));
248
+ if (!NIL_P(rb_show)) {
249
+ push_commit(w->walk, rb_show, 0);
250
+ }
251
+
252
+ rb_hide = rb_hash_lookup(rb_options, CSTR2SYM("hide"));
253
+ if (!NIL_P(rb_hide)) {
254
+ push_commit(w->walk, rb_hide, 1);
255
+ }
256
+
257
+ rb_simp = rb_hash_lookup(rb_options, CSTR2SYM("simplify"));
258
+ if (RTEST(rb_simp)) {
259
+ git_revwalk_simplify_first_parent(w->walk);
260
+ }
261
+
262
+ rb_oid_only = rb_hash_lookup(rb_options, CSTR2SYM("oid_only"));
263
+ if (RTEST(rb_oid_only)) {
264
+ w->oid_only = 1;
265
+ }
266
+
267
+ return Qnil;
268
+ }
269
+
270
+ static VALUE do_walk(VALUE _payload)
271
+ {
272
+ struct walk_options *w = (struct walk_options *)_payload;
273
+ int error;
274
+ git_oid commit_oid;
275
+
276
+ while ((error = git_revwalk_next(&commit_oid, w->walk)) == 0) {
277
+ if (w->offset > 0) {
278
+ w->offset--;
279
+ continue;
280
+ }
281
+
282
+ if (w->oid_only) {
283
+ rb_yield(rugged_create_oid(&commit_oid));
284
+ } else {
285
+ git_commit *commit;
286
+
287
+ error = git_commit_lookup(&commit, w->repo, &commit_oid);
288
+ rugged_exception_check(error);
289
+
290
+ rb_yield(
291
+ rugged_object_new(w->rb_owner, (git_object *)commit)
292
+ );
293
+ }
294
+
295
+ if (--w->limit == 0)
296
+ break;
297
+ }
298
+
299
+ if (error != GIT_ITEROVER)
300
+ rugged_exception_check(error);
301
+
302
+ return Qnil;
303
+ }
304
+
305
+ /*
306
+ * call-seq:
307
+ * Rugged::Walker.walk(repo, options={}) { |commit| block }
308
+ *
309
+ * Create a Walker object, initialize it with the given options
310
+ * and perform a walk on the repository; the lifetime of the
311
+ * walker is bound to the call and it is immediately cleaned
312
+ * up after the walk is over.
313
+ *
314
+ * The following options are available:
315
+ *
316
+ * - +sort+: Sorting mode for the walk (or an OR combination
317
+ * of several sorting modes).
318
+ *
319
+ * - +show+: Tips of the repository that will be walked;
320
+ * this is necessary for the walk to yield any results.
321
+ * A tip can be a 40-char object ID, an existing +Rugged::Commit+
322
+ * object, a reference, or an +Array+ of several of these
323
+ * (if you'd like to walk several tips in parallel).
324
+ *
325
+ * - +hide+: Same as +show+, but hides the given tips instead
326
+ * so they don't appear on the walk.
327
+ *
328
+ * - +oid_only+: if +true+, the walker will yield 40-char OIDs
329
+ * for each commit, instead of real +Rugged::Commit+ objects.
330
+ * Defaults to +false+.
331
+ *
332
+ * - +simplify+: if +true+, the walk will be simplified
333
+ * to the first parent of each commit.
334
+ *
335
+ * Example:
336
+ *
337
+ * Rugged::Walker.walk(repo,
338
+ * show: "92b22bbcb37caf4f6f53d30292169e84f5e4283b",
339
+ * sort: Rugged::SORT_DATE|Rugged::SORT_TOPO,
340
+ * oid_only: true) do |commit_oid|
341
+ * puts commit_oid
342
+ * end
343
+ *
344
+ * generates:
345
+ *
346
+ * 92b22bbcb37caf4f6f53d30292169e84f5e4283b
347
+ * 6b750d5800439b502de669465b385e5f469c78b6
348
+ * ef9207141549f4ffcd3c4597e270d32e10d0a6bc
349
+ * cb75e05f0f8ac3407fb3bd0ebd5ff07573b16c9f
350
+ * ...
351
+ */
352
+ static VALUE rb_git_walk(int argc, VALUE *argv, VALUE self)
353
+ {
354
+ VALUE rb_repo, rb_options;
355
+ struct walk_options w;
356
+ int exception = 0;
357
+
358
+ rb_scan_args(argc, argv, "10:", &rb_repo, &rb_options);
359
+
360
+ if (!rb_block_given_p()) {
361
+ ID iter_method = ID2SYM(rb_intern("walk"));
362
+ return rb_funcall(self, rb_intern("to_enum"), 3,
363
+ iter_method, rb_repo, rb_options);
364
+ }
365
+
366
+ Data_Get_Struct(rb_repo, git_repository, w.repo);
367
+ rugged_exception_check(git_revwalk_new(&w.walk, w.repo));
368
+
369
+ w.rb_owner = rb_repo;
370
+ w.rb_options = rb_options;
371
+
372
+ w.oid_only = 0;
373
+ w.offset = 0;
374
+ w.limit = UINT64_MAX;
375
+
376
+ if (!NIL_P(w.rb_options))
377
+ rb_protect(load_all_options, (VALUE)&w, &exception);
378
+
379
+ if (!exception)
380
+ rb_protect(do_walk, (VALUE)&w, &exception);
381
+
382
+ git_revwalk_free(w.walk);
383
+
384
+ if (exception)
385
+ rb_jump_tag(exception);
386
+
387
+ return Qnil;
388
+ }
389
+
390
+ static VALUE rb_git_walk_with_opts(int argc, VALUE *argv, VALUE self, int oid_only)
391
+ {
392
+ VALUE rb_options;
393
+ struct walk_options w;
394
+
395
+ rb_scan_args(argc, argv, "01", &rb_options);
396
+
397
+ if (!rb_block_given_p()) {
398
+ ID iter_method = ID2SYM(rb_intern(oid_only ? "each_oid" : "each"));
399
+ return rb_funcall(self, rb_intern("to_enum"), 2, iter_method, rb_options);
400
+ }
401
+
402
+ Data_Get_Struct(self, git_revwalk, w.walk);
403
+ w.repo = git_revwalk_repository(w.walk);
404
+
405
+ w.rb_owner = rugged_owner(self);
406
+ w.rb_options = Qnil;
407
+
408
+ w.oid_only = oid_only;
409
+ w.offset = 0;
410
+ w.limit = UINT64_MAX;
411
+
412
+ if (!NIL_P(rb_options))
413
+ load_walk_limits(&w, rb_options);
414
+
415
+ return do_walk((VALUE)&w);
416
+ }
417
+
418
+ /*
419
+ * call-seq:
420
+ * walker.each { |commit| block }
421
+ * walker.each -> Iterator
422
+ *
423
+ * Perform the walk through the repository, yielding each
424
+ * one of the commits found as a <tt>Rugged::Commit</tt> instance
425
+ * to +block+.
426
+ *
427
+ * If no +block+ is given, an +Iterator+ will be returned.
428
+ *
429
+ * The walker must have been previously set-up before a walk can be performed
430
+ * (i.e. at least one commit must have been pushed).
431
+ *
432
+ * walker.push("92b22bbcb37caf4f6f53d30292169e84f5e4283b")
433
+ * walker.each { |commit| puts commit.oid }
434
+ *
435
+ * generates:
436
+ *
437
+ * 92b22bbcb37caf4f6f53d30292169e84f5e4283b
438
+ * 6b750d5800439b502de669465b385e5f469c78b6
439
+ * ef9207141549f4ffcd3c4597e270d32e10d0a6bc
440
+ * cb75e05f0f8ac3407fb3bd0ebd5ff07573b16c9f
441
+ * ...
442
+ */
443
+ static VALUE rb_git_walker_each(int argc, VALUE *argv, VALUE self)
444
+ {
445
+ return rb_git_walk_with_opts(argc, argv, self, 0);
446
+ }
447
+
448
+ /*
449
+ * call-seq:
450
+ * walker.each_oid { |commit| block }
451
+ * walker.each_oid -> Iterator
452
+ *
453
+ * Perform the walk through the repository, yielding each
454
+ * one of the commit oids found as a <tt>String</tt>
455
+ * to +block+.
456
+ *
457
+ * If no +block+ is given, an +Iterator+ will be returned.
458
+ *
459
+ * The walker must have been previously set-up before a walk can be performed
460
+ * (i.e. at least one commit must have been pushed).
461
+ *
462
+ * walker.push("92b22bbcb37caf4f6f53d30292169e84f5e4283b")
463
+ * walker.each { |commit_oid| puts commit_oid }
464
+ *
465
+ * generates:
466
+ *
467
+ * 92b22bbcb37caf4f6f53d30292169e84f5e4283b
468
+ * 6b750d5800439b502de669465b385e5f469c78b6
469
+ * ef9207141549f4ffcd3c4597e270d32e10d0a6bc
470
+ * cb75e05f0f8ac3407fb3bd0ebd5ff07573b16c9f
471
+ * ...
472
+ */
473
+ static VALUE rb_git_walker_each_oid(int argc, VALUE *argv, VALUE self)
474
+ {
475
+ return rb_git_walk_with_opts(argc, argv, self, 1);
476
+ }
477
+
478
+
479
+
480
+ void Init_rugged_revwalk(void)
481
+ {
482
+ rb_cRuggedWalker = rb_define_class_under(rb_mRugged, "Walker", rb_cObject);
483
+ rb_define_singleton_method(rb_cRuggedWalker, "new", rb_git_walker_new, 1);
484
+ rb_define_singleton_method(rb_cRuggedWalker, "walk", rb_git_walk, -1);
485
+
486
+ rb_define_method(rb_cRuggedWalker, "push", rb_git_walker_push, 1);
487
+ rb_define_method(rb_cRuggedWalker, "push_range", rb_git_walker_push_range, 1);
488
+ rb_define_method(rb_cRuggedWalker, "each", rb_git_walker_each, -1);
489
+ rb_define_method(rb_cRuggedWalker, "each_oid", rb_git_walker_each_oid, -1);
490
+ rb_define_method(rb_cRuggedWalker, "walk", rb_git_walker_each, -1);
491
+ rb_define_method(rb_cRuggedWalker, "hide", rb_git_walker_hide, 1);
492
+ rb_define_method(rb_cRuggedWalker, "reset", rb_git_walker_reset, 0);
493
+ rb_define_method(rb_cRuggedWalker, "sorting", rb_git_walker_sorting, 1);
494
+ rb_define_method(rb_cRuggedWalker, "simplify_first_parent", rb_git_walker_simplify_first_parent, 0);
495
+ }