rdavila-rugged 0.24.0b13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.md +619 -0
- data/ext/rugged/extconf.rb +105 -0
- data/ext/rugged/rugged.c +527 -0
- data/ext/rugged/rugged.h +185 -0
- data/ext/rugged/rugged_backend.c +34 -0
- data/ext/rugged/rugged_blame.c +292 -0
- data/ext/rugged/rugged_blob.c +638 -0
- data/ext/rugged/rugged_branch.c +195 -0
- data/ext/rugged/rugged_branch_collection.c +408 -0
- data/ext/rugged/rugged_commit.c +691 -0
- data/ext/rugged/rugged_config.c +404 -0
- data/ext/rugged/rugged_cred.c +148 -0
- data/ext/rugged/rugged_diff.c +686 -0
- data/ext/rugged/rugged_diff_delta.c +105 -0
- data/ext/rugged/rugged_diff_hunk.c +103 -0
- data/ext/rugged/rugged_diff_line.c +83 -0
- data/ext/rugged/rugged_index.c +1255 -0
- data/ext/rugged/rugged_note.c +376 -0
- data/ext/rugged/rugged_object.c +383 -0
- data/ext/rugged/rugged_patch.c +245 -0
- data/ext/rugged/rugged_reference.c +396 -0
- data/ext/rugged/rugged_reference_collection.c +446 -0
- data/ext/rugged/rugged_remote.c +691 -0
- data/ext/rugged/rugged_remote_collection.c +457 -0
- data/ext/rugged/rugged_repo.c +2669 -0
- data/ext/rugged/rugged_revwalk.c +495 -0
- data/ext/rugged/rugged_settings.c +155 -0
- data/ext/rugged/rugged_signature.c +106 -0
- data/ext/rugged/rugged_submodule.c +852 -0
- data/ext/rugged/rugged_submodule_collection.c +384 -0
- data/ext/rugged/rugged_tag.c +251 -0
- data/ext/rugged/rugged_tag_collection.c +347 -0
- data/ext/rugged/rugged_tree.c +919 -0
- data/lib/rugged.rb +23 -0
- data/lib/rugged/attributes.rb +41 -0
- data/lib/rugged/blob.rb +28 -0
- data/lib/rugged/branch.rb +19 -0
- data/lib/rugged/commit.rb +54 -0
- data/lib/rugged/console.rb +9 -0
- data/lib/rugged/credentials.rb +43 -0
- data/lib/rugged/diff.rb +20 -0
- data/lib/rugged/diff/delta.rb +53 -0
- data/lib/rugged/diff/hunk.rb +18 -0
- data/lib/rugged/diff/line.rb +47 -0
- data/lib/rugged/index.rb +13 -0
- data/lib/rugged/object.rb +7 -0
- data/lib/rugged/patch.rb +36 -0
- data/lib/rugged/reference.rb +7 -0
- data/lib/rugged/remote.rb +4 -0
- data/lib/rugged/repository.rb +227 -0
- data/lib/rugged/submodule_collection.rb +48 -0
- data/lib/rugged/tag.rb +50 -0
- data/lib/rugged/tree.rb +38 -0
- data/lib/rugged/version.rb +3 -0
- data/lib/rugged/walker.rb +5 -0
- metadata +146 -0
@@ -0,0 +1,376 @@
|
|
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_cRuggedRepo;
|
28
|
+
extern VALUE rb_cRuggedObject;
|
29
|
+
|
30
|
+
static VALUE rugged_git_note_message(const git_note *note)
|
31
|
+
{
|
32
|
+
const char *message;
|
33
|
+
message = git_note_message(note);
|
34
|
+
|
35
|
+
/*
|
36
|
+
* assume the note message is utf8 compatible, because that's
|
37
|
+
* the sensible thing to do.
|
38
|
+
*/
|
39
|
+
return rb_str_new_utf8(message);
|
40
|
+
}
|
41
|
+
|
42
|
+
static VALUE rugged_git_note_oid(const git_note* note)
|
43
|
+
{
|
44
|
+
const git_oid *oid;
|
45
|
+
oid = git_note_id(note);
|
46
|
+
|
47
|
+
return rugged_create_oid(oid);
|
48
|
+
}
|
49
|
+
|
50
|
+
/*
|
51
|
+
* call-seq:
|
52
|
+
* obj.notes(notes_ref = 'refs/notes/commits') -> hash
|
53
|
+
*
|
54
|
+
* Lookup a note for +obj+ from +notes_ref+:
|
55
|
+
* - +notes_ref+: (optional): canonical name of the reference to use, defaults to "refs/notes/commits"
|
56
|
+
*
|
57
|
+
* Returns a new Hash object.
|
58
|
+
*
|
59
|
+
* obj.notes #=> {:message=>"note text\n", :oid=>"94eca2de348d5f672faf56b0decafa5937e3235e"}
|
60
|
+
*/
|
61
|
+
static VALUE rb_git_note_lookup(int argc, VALUE *argv, VALUE self)
|
62
|
+
{
|
63
|
+
git_repository *repo;
|
64
|
+
const char *notes_ref = NULL;
|
65
|
+
VALUE rb_notes_ref;
|
66
|
+
VALUE rb_note_hash;
|
67
|
+
VALUE owner;
|
68
|
+
git_note *note;
|
69
|
+
git_object *object;
|
70
|
+
int error;
|
71
|
+
|
72
|
+
rb_scan_args(argc, argv, "01", &rb_notes_ref);
|
73
|
+
|
74
|
+
if (!NIL_P(rb_notes_ref)) {
|
75
|
+
Check_Type(rb_notes_ref, T_STRING);
|
76
|
+
notes_ref = StringValueCStr(rb_notes_ref);
|
77
|
+
}
|
78
|
+
|
79
|
+
Data_Get_Struct(self, git_object, object);
|
80
|
+
|
81
|
+
owner = rugged_owner(self);
|
82
|
+
Data_Get_Struct(owner, git_repository, repo);
|
83
|
+
|
84
|
+
error = git_note_read(¬e, repo, notes_ref, git_object_id(object));
|
85
|
+
|
86
|
+
if (error == GIT_ENOTFOUND)
|
87
|
+
return Qnil;
|
88
|
+
|
89
|
+
rugged_exception_check(error);
|
90
|
+
|
91
|
+
rb_note_hash = rb_hash_new();
|
92
|
+
rb_hash_aset(rb_note_hash, CSTR2SYM("message"), rugged_git_note_message(note));
|
93
|
+
rb_hash_aset(rb_note_hash, CSTR2SYM("oid"), rugged_git_note_oid(note));
|
94
|
+
|
95
|
+
git_note_free(note);
|
96
|
+
|
97
|
+
return rb_note_hash;
|
98
|
+
}
|
99
|
+
|
100
|
+
/*
|
101
|
+
* call-seq:
|
102
|
+
* obj.create_note(data = {}) -> oid
|
103
|
+
*
|
104
|
+
* Write a new +note+ to +object+, with the given +data+
|
105
|
+
* arguments, passed as a +Hash+:
|
106
|
+
*
|
107
|
+
* - +:message+: the content of the note to add to the object
|
108
|
+
* - +:committer+: (optional) a hash with the signature for the committer
|
109
|
+
* defaults to the signature from the configuration
|
110
|
+
* - +:author+: (optional) a hash with the signature for the author
|
111
|
+
* defaults to the signature from the configuration
|
112
|
+
* - +:ref+: (optional): canonical name of the reference to use, defaults to "refs/notes/commits"
|
113
|
+
* - +:force+: (optional): overwrite existing note (disabled by default)
|
114
|
+
*
|
115
|
+
* When the note is successfully written to disk, its +oid+ will be
|
116
|
+
* returned as a hex +String+.
|
117
|
+
*
|
118
|
+
* author = {:email=>"tanoku@gmail.com", :time=>Time.now, :name=>"Vicent Mart\303\255"}
|
119
|
+
*
|
120
|
+
* obj.create_note(
|
121
|
+
* :author => author,
|
122
|
+
* :committer => author,
|
123
|
+
* :message => "Hello world\n\n",
|
124
|
+
* :ref => 'refs/notes/builds'
|
125
|
+
* )
|
126
|
+
*/
|
127
|
+
static VALUE rb_git_note_create(VALUE self, VALUE rb_data)
|
128
|
+
{
|
129
|
+
VALUE rb_ref, rb_message, rb_force;
|
130
|
+
git_repository *repo = NULL;
|
131
|
+
const char *notes_ref = NULL;
|
132
|
+
|
133
|
+
VALUE owner;
|
134
|
+
|
135
|
+
git_signature *author, *committer;
|
136
|
+
git_oid note_oid;
|
137
|
+
|
138
|
+
git_object *target = NULL;
|
139
|
+
int error = 0;
|
140
|
+
int force = 0;
|
141
|
+
|
142
|
+
Check_Type(rb_data, T_HASH);
|
143
|
+
|
144
|
+
Data_Get_Struct(self, git_object, target);
|
145
|
+
|
146
|
+
owner = rugged_owner(self);
|
147
|
+
Data_Get_Struct(owner, git_repository, repo);
|
148
|
+
|
149
|
+
rb_ref = rb_hash_aref(rb_data, CSTR2SYM("ref"));
|
150
|
+
|
151
|
+
rb_force = rb_hash_aref(rb_data, CSTR2SYM("force"));
|
152
|
+
if (!NIL_P(rb_force))
|
153
|
+
force = rugged_parse_bool(rb_force);
|
154
|
+
|
155
|
+
if (!NIL_P(rb_ref)) {
|
156
|
+
Check_Type(rb_ref, T_STRING);
|
157
|
+
notes_ref = StringValueCStr(rb_ref);
|
158
|
+
}
|
159
|
+
|
160
|
+
rb_message = rb_hash_aref(rb_data, CSTR2SYM("message"));
|
161
|
+
Check_Type(rb_message, T_STRING);
|
162
|
+
|
163
|
+
committer = rugged_signature_get(
|
164
|
+
rb_hash_aref(rb_data, CSTR2SYM("committer")), repo
|
165
|
+
);
|
166
|
+
|
167
|
+
author = rugged_signature_get(
|
168
|
+
rb_hash_aref(rb_data, CSTR2SYM("author")), repo
|
169
|
+
);
|
170
|
+
|
171
|
+
error = git_note_create(
|
172
|
+
¬e_oid,
|
173
|
+
repo,
|
174
|
+
notes_ref,
|
175
|
+
author,
|
176
|
+
committer,
|
177
|
+
git_object_id(target),
|
178
|
+
StringValueCStr(rb_message),
|
179
|
+
force);
|
180
|
+
|
181
|
+
|
182
|
+
git_signature_free(author);
|
183
|
+
git_signature_free(committer);
|
184
|
+
|
185
|
+
rugged_exception_check(error);
|
186
|
+
|
187
|
+
return rugged_create_oid(¬e_oid);
|
188
|
+
}
|
189
|
+
|
190
|
+
/*
|
191
|
+
* call-seq:
|
192
|
+
* obj.remove_note(data = {}) -> boolean
|
193
|
+
*
|
194
|
+
* Removes a +note+ from +object+, with the given +data+
|
195
|
+
* arguments, passed as a +Hash+:
|
196
|
+
*
|
197
|
+
* - +:committer+ (optional): a hash with the signature for the committer,
|
198
|
+
* defaults to the signature from the configuration
|
199
|
+
* - +:author+ (optional): a hash with the signature for the author,
|
200
|
+
* defaults to the signature from the configuration
|
201
|
+
* - +:ref+: (optional): canonical name of the reference to use, defaults to "refs/notes/commits"
|
202
|
+
*
|
203
|
+
* When the note is successfully removed +true+ will be
|
204
|
+
* returned as a +Boolean+.
|
205
|
+
*
|
206
|
+
* author = {:email=>"tanoku@gmail.com", :time=>Time.now, :name=>"Vicent Mart\303\255"}
|
207
|
+
*
|
208
|
+
* obj.remove_note(
|
209
|
+
* :author => author,
|
210
|
+
* :committer => author,
|
211
|
+
* :ref => 'refs/notes/builds'
|
212
|
+
* )
|
213
|
+
*/
|
214
|
+
static VALUE rb_git_note_remove(int argc, VALUE *argv, VALUE self)
|
215
|
+
{
|
216
|
+
int error = 0;
|
217
|
+
const char *notes_ref = NULL;
|
218
|
+
git_repository *repo = NULL;
|
219
|
+
git_signature *author, *committer;
|
220
|
+
git_object *target = NULL;
|
221
|
+
VALUE rb_data;
|
222
|
+
VALUE rb_ref = Qnil;
|
223
|
+
VALUE rb_author = Qnil;
|
224
|
+
VALUE rb_committer = Qnil;
|
225
|
+
VALUE owner;
|
226
|
+
|
227
|
+
Data_Get_Struct(self, git_object, target);
|
228
|
+
|
229
|
+
owner = rugged_owner(self);
|
230
|
+
Data_Get_Struct(owner, git_repository, repo);
|
231
|
+
|
232
|
+
rb_scan_args(argc, argv, "01", &rb_data);
|
233
|
+
|
234
|
+
if (!NIL_P(rb_data)) {
|
235
|
+
Check_Type(rb_data, T_HASH);
|
236
|
+
|
237
|
+
rb_ref = rb_hash_aref(rb_data, CSTR2SYM("ref"));
|
238
|
+
if (!NIL_P(rb_ref)) {
|
239
|
+
Check_Type(rb_ref, T_STRING);
|
240
|
+
notes_ref = StringValueCStr(rb_ref);
|
241
|
+
}
|
242
|
+
|
243
|
+
rb_committer = rb_hash_aref(rb_data, CSTR2SYM("committer"));
|
244
|
+
rb_author = rb_hash_aref(rb_data, CSTR2SYM("author"));
|
245
|
+
}
|
246
|
+
|
247
|
+
committer = rugged_signature_get(rb_committer, repo);
|
248
|
+
author = rugged_signature_get(rb_author, repo);
|
249
|
+
|
250
|
+
error = git_note_remove(
|
251
|
+
repo,
|
252
|
+
notes_ref,
|
253
|
+
author,
|
254
|
+
committer,
|
255
|
+
git_object_id(target));
|
256
|
+
|
257
|
+
git_signature_free(author);
|
258
|
+
git_signature_free(committer);
|
259
|
+
|
260
|
+
if (error == GIT_ENOTFOUND)
|
261
|
+
return Qfalse;
|
262
|
+
|
263
|
+
rugged_exception_check(error);
|
264
|
+
|
265
|
+
return Qtrue;
|
266
|
+
}
|
267
|
+
|
268
|
+
static int cb_note__each(const git_oid *blob_id, const git_oid *annotated_object_id, void *data)
|
269
|
+
{
|
270
|
+
VALUE rb_args = rb_ary_new2(2);
|
271
|
+
struct rugged_cb_payload *payload = data;
|
272
|
+
git_object *annotated_object;
|
273
|
+
git_object *note_blob;
|
274
|
+
|
275
|
+
git_repository *repo;
|
276
|
+
|
277
|
+
Data_Get_Struct(payload->rb_data, git_repository, repo);
|
278
|
+
|
279
|
+
rugged_exception_check(
|
280
|
+
git_object_lookup(&annotated_object, repo, annotated_object_id, GIT_OBJ_ANY)
|
281
|
+
);
|
282
|
+
|
283
|
+
rugged_exception_check(
|
284
|
+
git_object_lookup(¬e_blob, repo, blob_id, GIT_OBJ_BLOB)
|
285
|
+
);
|
286
|
+
|
287
|
+
rb_ary_push(rb_args, rugged_object_new(payload->rb_data, note_blob));
|
288
|
+
rb_ary_push(rb_args, rugged_object_new(payload->rb_data, annotated_object));
|
289
|
+
|
290
|
+
rb_protect(rb_yield_splat, rb_args, &payload->exception);
|
291
|
+
|
292
|
+
return payload->exception ? GIT_ERROR : GIT_OK;
|
293
|
+
}
|
294
|
+
|
295
|
+
/*
|
296
|
+
* call-seq:
|
297
|
+
* repo.each_note(notes_ref = "refs/notes/commits") { |note_blob, annotated_object| block }
|
298
|
+
* repo.each_note(notes_ref = "refs/notes/commits") -> an_enumerator
|
299
|
+
*
|
300
|
+
* Call the given block once for each note_blob/annotated_object pair in +repository+
|
301
|
+
* - +notes_ref+: (optional): canonical name of the reference to use defaults to "refs/notes/commits"
|
302
|
+
*
|
303
|
+
* If no block is given, an +Enumerator+ is returned.
|
304
|
+
*
|
305
|
+
* @repo.each_note do |note_blob, annotated_object|
|
306
|
+
* puts "#{note_blob.oid} => #{annotated_object.oid}"
|
307
|
+
* end
|
308
|
+
*/
|
309
|
+
static VALUE rb_git_note_each(int argc, VALUE *argv, VALUE self)
|
310
|
+
{
|
311
|
+
git_repository *repo;
|
312
|
+
const char *notes_ref = NULL;
|
313
|
+
int error;
|
314
|
+
struct rugged_cb_payload payload = { self, 0 };
|
315
|
+
VALUE rb_notes_ref;
|
316
|
+
|
317
|
+
rb_scan_args(argc, argv, "01", &rb_notes_ref);
|
318
|
+
|
319
|
+
if (!rb_block_given_p()) {
|
320
|
+
return rb_funcall(self, rb_intern("to_enum"), 3, CSTR2SYM("each_note"), self, rb_notes_ref);
|
321
|
+
}
|
322
|
+
|
323
|
+
if (!NIL_P(rb_notes_ref)) {
|
324
|
+
Check_Type(rb_notes_ref, T_STRING);
|
325
|
+
notes_ref = StringValueCStr(rb_notes_ref);
|
326
|
+
}
|
327
|
+
|
328
|
+
Data_Get_Struct(self, git_repository, repo);
|
329
|
+
|
330
|
+
error = git_note_foreach(repo, notes_ref, &cb_note__each, &payload);
|
331
|
+
|
332
|
+
if (payload.exception)
|
333
|
+
rb_jump_tag(payload.exception);
|
334
|
+
rugged_exception_check(error);
|
335
|
+
|
336
|
+
return Qnil;
|
337
|
+
}
|
338
|
+
|
339
|
+
/*
|
340
|
+
* call-seq:
|
341
|
+
* repo.notes_default_ref() -> string
|
342
|
+
*
|
343
|
+
* Get the default notes reference for a +repository+:
|
344
|
+
*
|
345
|
+
* Returns a new String object.
|
346
|
+
*
|
347
|
+
* repo.default_notes_ref #=> "refs/notes/commits"
|
348
|
+
*/
|
349
|
+
static VALUE rb_git_note_default_ref_GET(VALUE self)
|
350
|
+
{
|
351
|
+
git_repository *repo = NULL;
|
352
|
+
git_buf ref_name = { 0 };
|
353
|
+
VALUE rb_result;
|
354
|
+
|
355
|
+
Data_Get_Struct(self, git_repository, repo);
|
356
|
+
|
357
|
+
rugged_exception_check(
|
358
|
+
git_note_default_ref(&ref_name, repo)
|
359
|
+
);
|
360
|
+
|
361
|
+
rb_result = rb_enc_str_new(ref_name.ptr, ref_name.size, rb_utf8_encoding());
|
362
|
+
|
363
|
+
git_buf_free(&ref_name);
|
364
|
+
|
365
|
+
return rb_result;
|
366
|
+
}
|
367
|
+
|
368
|
+
void Init_rugged_notes(void)
|
369
|
+
{
|
370
|
+
rb_define_method(rb_cRuggedObject, "notes", rb_git_note_lookup, -1);
|
371
|
+
rb_define_method(rb_cRuggedObject, "create_note", rb_git_note_create, 1);
|
372
|
+
rb_define_method(rb_cRuggedObject, "remove_note", rb_git_note_remove, -1);
|
373
|
+
|
374
|
+
rb_define_method(rb_cRuggedRepo, "each_note", rb_git_note_each, -1);
|
375
|
+
rb_define_method(rb_cRuggedRepo, "default_notes_ref", rb_git_note_default_ref_GET, 0);
|
376
|
+
}
|
@@ -0,0 +1,383 @@
|
|
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_cRuggedTagAnnotation;
|
29
|
+
extern VALUE rb_cRuggedTree;
|
30
|
+
extern VALUE rb_cRuggedCommit;
|
31
|
+
extern VALUE rb_cRuggedBlob;
|
32
|
+
extern VALUE rb_cRuggedRepo;
|
33
|
+
|
34
|
+
VALUE rb_cRuggedObject;
|
35
|
+
|
36
|
+
git_otype rugged_otype_get(VALUE self)
|
37
|
+
{
|
38
|
+
git_otype type = GIT_OBJ_BAD;
|
39
|
+
|
40
|
+
if (NIL_P(self))
|
41
|
+
return GIT_OBJ_ANY;
|
42
|
+
|
43
|
+
switch (TYPE(self)) {
|
44
|
+
case T_STRING:
|
45
|
+
type = git_object_string2type(StringValueCStr(self));
|
46
|
+
break;
|
47
|
+
|
48
|
+
case T_FIXNUM:
|
49
|
+
type = FIX2INT(self);
|
50
|
+
break;
|
51
|
+
|
52
|
+
case T_SYMBOL: {
|
53
|
+
ID t = SYM2ID(self);
|
54
|
+
|
55
|
+
if (t == rb_intern("commit"))
|
56
|
+
type = GIT_OBJ_COMMIT;
|
57
|
+
else if (t == rb_intern("tree"))
|
58
|
+
type = GIT_OBJ_TREE;
|
59
|
+
else if (t == rb_intern("tag"))
|
60
|
+
type = GIT_OBJ_TAG;
|
61
|
+
else if (t == rb_intern("blob"))
|
62
|
+
type = GIT_OBJ_BLOB;
|
63
|
+
}
|
64
|
+
}
|
65
|
+
|
66
|
+
if (!git_object_typeisloose(type))
|
67
|
+
rb_raise(rb_eTypeError, "Invalid Git object type specifier");
|
68
|
+
|
69
|
+
return type;
|
70
|
+
}
|
71
|
+
|
72
|
+
VALUE rugged_otype_new(git_otype t)
|
73
|
+
{
|
74
|
+
switch (t) {
|
75
|
+
case GIT_OBJ_COMMIT:
|
76
|
+
return CSTR2SYM("commit");
|
77
|
+
case GIT_OBJ_TAG:
|
78
|
+
return CSTR2SYM("tag");
|
79
|
+
case GIT_OBJ_TREE:
|
80
|
+
return CSTR2SYM("tree");
|
81
|
+
case GIT_OBJ_BLOB:
|
82
|
+
return CSTR2SYM("blob");
|
83
|
+
default:
|
84
|
+
return Qnil;
|
85
|
+
}
|
86
|
+
}
|
87
|
+
|
88
|
+
int rugged_oid_get(git_oid *oid, git_repository *repo, VALUE p)
|
89
|
+
{
|
90
|
+
git_object *object;
|
91
|
+
int error;
|
92
|
+
|
93
|
+
if (rb_obj_is_kind_of(p, rb_cRuggedObject)) {
|
94
|
+
Data_Get_Struct(p, git_object, object);
|
95
|
+
git_oid_cpy(oid, git_object_id(object));
|
96
|
+
} else {
|
97
|
+
Check_Type(p, T_STRING);
|
98
|
+
|
99
|
+
/* Fast path: see if the 40-char string is an OID */
|
100
|
+
if (RSTRING_LEN(p) == 40 &&
|
101
|
+
git_oid_fromstr(oid, RSTRING_PTR(p)) == 0)
|
102
|
+
return GIT_OK;
|
103
|
+
|
104
|
+
if ((error = git_revparse_single(&object, repo, StringValueCStr(p))))
|
105
|
+
return error;
|
106
|
+
|
107
|
+
git_oid_cpy(oid, git_object_id(object));
|
108
|
+
git_object_free(object);
|
109
|
+
}
|
110
|
+
|
111
|
+
return GIT_OK;
|
112
|
+
}
|
113
|
+
|
114
|
+
git_object *rugged_object_get(git_repository *repo, VALUE object_value, git_otype type)
|
115
|
+
{
|
116
|
+
git_object *object = NULL;
|
117
|
+
|
118
|
+
if (rb_obj_is_kind_of(object_value, rb_cRuggedObject)) {
|
119
|
+
git_object *owned_obj = NULL;
|
120
|
+
Data_Get_Struct(object_value, git_object, owned_obj);
|
121
|
+
git_object_dup(&object, owned_obj);
|
122
|
+
} else {
|
123
|
+
int error;
|
124
|
+
|
125
|
+
Check_Type(object_value, T_STRING);
|
126
|
+
|
127
|
+
/* Fast path: if we have a 40-char string, just perform the lookup directly */
|
128
|
+
if (RSTRING_LEN(object_value) == 40) {
|
129
|
+
git_oid oid;
|
130
|
+
|
131
|
+
/* If it's not an OID, we can still try the revparse */
|
132
|
+
if (git_oid_fromstr(&oid, RSTRING_PTR(object_value)) == 0) {
|
133
|
+
error = git_object_lookup(&object, repo, &oid, type);
|
134
|
+
rugged_exception_check(error);
|
135
|
+
return object;
|
136
|
+
}
|
137
|
+
}
|
138
|
+
|
139
|
+
/* Otherwise, assume the string is a revlist and try to parse it */
|
140
|
+
error = git_revparse_single(&object, repo, StringValueCStr(object_value));
|
141
|
+
rugged_exception_check(error);
|
142
|
+
}
|
143
|
+
|
144
|
+
assert(object);
|
145
|
+
|
146
|
+
if (type != GIT_OBJ_ANY && git_object_type(object) != type)
|
147
|
+
rb_raise(rb_eArgError, "Object is not of the required type");
|
148
|
+
|
149
|
+
return object;
|
150
|
+
}
|
151
|
+
|
152
|
+
static void rb_git_object__free(git_object *object)
|
153
|
+
{
|
154
|
+
git_object_free(object);
|
155
|
+
}
|
156
|
+
|
157
|
+
VALUE rugged_object_new(VALUE owner, git_object *object)
|
158
|
+
{
|
159
|
+
VALUE klass, rb_object;
|
160
|
+
|
161
|
+
switch (git_object_type(object))
|
162
|
+
{
|
163
|
+
case GIT_OBJ_COMMIT:
|
164
|
+
klass = rb_cRuggedCommit;
|
165
|
+
break;
|
166
|
+
|
167
|
+
case GIT_OBJ_TAG:
|
168
|
+
klass = rb_cRuggedTagAnnotation;
|
169
|
+
break;
|
170
|
+
|
171
|
+
case GIT_OBJ_TREE:
|
172
|
+
klass = rb_cRuggedTree;
|
173
|
+
break;
|
174
|
+
|
175
|
+
case GIT_OBJ_BLOB:
|
176
|
+
klass = rb_cRuggedBlob;
|
177
|
+
break;
|
178
|
+
|
179
|
+
default:
|
180
|
+
rb_raise(rb_eTypeError, "Invalid type for Rugged::Object");
|
181
|
+
return Qnil; /* never reached */
|
182
|
+
}
|
183
|
+
|
184
|
+
rb_object = Data_Wrap_Struct(klass, NULL, &rb_git_object__free, object);
|
185
|
+
rugged_set_owner(rb_object, owner);
|
186
|
+
return rb_object;
|
187
|
+
}
|
188
|
+
|
189
|
+
|
190
|
+
static git_otype class2otype(VALUE klass)
|
191
|
+
{
|
192
|
+
if (RTEST(rb_class_inherited_p(klass, rb_cRuggedCommit)))
|
193
|
+
return GIT_OBJ_COMMIT;
|
194
|
+
|
195
|
+
if (RTEST(rb_class_inherited_p(klass, rb_cRuggedTagAnnotation)))
|
196
|
+
return GIT_OBJ_TAG;
|
197
|
+
|
198
|
+
if (RTEST(rb_class_inherited_p(klass, rb_cRuggedBlob)))
|
199
|
+
return GIT_OBJ_BLOB;
|
200
|
+
|
201
|
+
if (RTEST(rb_class_inherited_p(klass, rb_cRuggedTree)))
|
202
|
+
return GIT_OBJ_TREE;
|
203
|
+
|
204
|
+
return GIT_OBJ_BAD;
|
205
|
+
}
|
206
|
+
|
207
|
+
/*
|
208
|
+
* call-seq:
|
209
|
+
* Object.new(repo, oid) -> object
|
210
|
+
* Object.lookup(repo, oid) -> object
|
211
|
+
*
|
212
|
+
* Find and return the git object inside +repo+ with the given +oid+.
|
213
|
+
*
|
214
|
+
* +oid+ can either have be the complete, 40 character string or any
|
215
|
+
* unique prefix.
|
216
|
+
*/
|
217
|
+
VALUE rb_git_object_lookup(VALUE klass, VALUE rb_repo, VALUE rb_hex)
|
218
|
+
{
|
219
|
+
git_object *object;
|
220
|
+
git_otype type;
|
221
|
+
git_oid oid;
|
222
|
+
int error;
|
223
|
+
int oid_length;
|
224
|
+
|
225
|
+
git_repository *repo;
|
226
|
+
|
227
|
+
type = class2otype(klass);
|
228
|
+
|
229
|
+
if (type == GIT_OBJ_BAD)
|
230
|
+
type = GIT_OBJ_ANY;
|
231
|
+
|
232
|
+
Check_Type(rb_hex, T_STRING);
|
233
|
+
oid_length = (int)RSTRING_LEN(rb_hex);
|
234
|
+
|
235
|
+
rugged_check_repo(rb_repo);
|
236
|
+
|
237
|
+
if (oid_length > GIT_OID_HEXSZ)
|
238
|
+
rb_raise(rb_eTypeError, "The given OID is too long");
|
239
|
+
|
240
|
+
Data_Get_Struct(rb_repo, git_repository, repo);
|
241
|
+
|
242
|
+
error = git_oid_fromstrn(&oid, RSTRING_PTR(rb_hex), oid_length);
|
243
|
+
rugged_exception_check(error);
|
244
|
+
|
245
|
+
if (oid_length < GIT_OID_HEXSZ)
|
246
|
+
error = git_object_lookup_prefix(&object, repo, &oid, oid_length, type);
|
247
|
+
else
|
248
|
+
error = git_object_lookup(&object, repo, &oid, type);
|
249
|
+
|
250
|
+
rugged_exception_check(error);
|
251
|
+
|
252
|
+
return rugged_object_new(rb_repo, object);
|
253
|
+
}
|
254
|
+
|
255
|
+
VALUE rugged_object_rev_parse(VALUE rb_repo, VALUE rb_spec, int as_obj)
|
256
|
+
{
|
257
|
+
git_object *object;
|
258
|
+
const char *spec;
|
259
|
+
int error;
|
260
|
+
git_repository *repo;
|
261
|
+
VALUE ret;
|
262
|
+
|
263
|
+
Check_Type(rb_spec, T_STRING);
|
264
|
+
spec = RSTRING_PTR(rb_spec);
|
265
|
+
|
266
|
+
rugged_check_repo(rb_repo);
|
267
|
+
|
268
|
+
Data_Get_Struct(rb_repo, git_repository, repo);
|
269
|
+
|
270
|
+
error = git_revparse_single(&object, repo, spec);
|
271
|
+
rugged_exception_check(error);
|
272
|
+
|
273
|
+
if (as_obj) {
|
274
|
+
return rugged_object_new(rb_repo, object);
|
275
|
+
}
|
276
|
+
|
277
|
+
ret = rugged_create_oid(git_object_id(object));
|
278
|
+
git_object_free(object);
|
279
|
+
return ret;
|
280
|
+
}
|
281
|
+
|
282
|
+
/*
|
283
|
+
* call-seq: Object.rev_parse(repo, str) -> object
|
284
|
+
*
|
285
|
+
* Find and return a single object inside +repo+ as specified by the
|
286
|
+
* git revision string +str+.
|
287
|
+
*
|
288
|
+
* See http://git-scm.com/docs/git-rev-parse.html#_specifying_revisions or
|
289
|
+
* <code>man gitrevisions</code> for information on the accepted syntax.
|
290
|
+
*
|
291
|
+
* Raises a Rugged::InvalidError if +str+ does not contain a valid revision string.
|
292
|
+
*/
|
293
|
+
VALUE rb_git_object_rev_parse(VALUE klass, VALUE rb_repo, VALUE rb_spec)
|
294
|
+
{
|
295
|
+
return rugged_object_rev_parse(rb_repo, rb_spec, 1);
|
296
|
+
}
|
297
|
+
|
298
|
+
/*
|
299
|
+
* call-seq: Object.rev_parse_oid(repo, str) -> oid
|
300
|
+
*
|
301
|
+
* Find and return the id of the object inside +repo+ as specified by the
|
302
|
+
* git revision string +str+.
|
303
|
+
*
|
304
|
+
* See http://git-scm.com/docs/git-rev-parse.html#_specifying_revisions or
|
305
|
+
* <code>man gitrevisions</code> for information on the accepted syntax.
|
306
|
+
*
|
307
|
+
* Raises a Rugged::InvalidError if +str+ does not contain a valid revision string.
|
308
|
+
*/
|
309
|
+
VALUE rb_git_object_rev_parse_oid(VALUE klass, VALUE rb_repo, VALUE rb_spec)
|
310
|
+
{
|
311
|
+
return rugged_object_rev_parse(rb_repo, rb_spec, 0);
|
312
|
+
}
|
313
|
+
|
314
|
+
/*
|
315
|
+
* call-seq: object == other
|
316
|
+
*
|
317
|
+
* Returns true only if +object+ and other are both instances or subclasses of
|
318
|
+
* Rugged::Object and have the same object id, false otherwise.
|
319
|
+
*/
|
320
|
+
static VALUE rb_git_object_equal(VALUE self, VALUE other)
|
321
|
+
{
|
322
|
+
git_object *a, *b;
|
323
|
+
|
324
|
+
if (!rb_obj_is_kind_of(other, rb_cRuggedObject))
|
325
|
+
return Qfalse;
|
326
|
+
|
327
|
+
Data_Get_Struct(self, git_object, a);
|
328
|
+
Data_Get_Struct(other, git_object, b);
|
329
|
+
|
330
|
+
return git_oid_cmp(git_object_id(a), git_object_id(b)) == 0 ? Qtrue : Qfalse;
|
331
|
+
}
|
332
|
+
|
333
|
+
/*
|
334
|
+
* call-seq: object.oid -> oid
|
335
|
+
*
|
336
|
+
* Return the Object ID (a 40 character SHA1 hash) for +object+.
|
337
|
+
*/
|
338
|
+
static VALUE rb_git_object_oid_GET(VALUE self)
|
339
|
+
{
|
340
|
+
git_object *object;
|
341
|
+
Data_Get_Struct(self, git_object, object);
|
342
|
+
return rugged_create_oid(git_object_id(object));
|
343
|
+
}
|
344
|
+
|
345
|
+
/*
|
346
|
+
* call-seq: object.type -> type
|
347
|
+
*
|
348
|
+
* Returns the object's type. Can be one of +:commit+, +:tag+, +:tree+ or +:blob+.
|
349
|
+
*/
|
350
|
+
static VALUE rb_git_object_type_GET(VALUE self)
|
351
|
+
{
|
352
|
+
git_object *object;
|
353
|
+
Data_Get_Struct(self, git_object, object);
|
354
|
+
|
355
|
+
return rugged_otype_new(git_object_type(object));
|
356
|
+
}
|
357
|
+
|
358
|
+
/*
|
359
|
+
* call-seq: object.read_raw -> raw_object
|
360
|
+
*
|
361
|
+
* Returns the git object as a Rugged::OdbObject instance.
|
362
|
+
*/
|
363
|
+
static VALUE rb_git_object_read_raw(VALUE self)
|
364
|
+
{
|
365
|
+
git_object *object;
|
366
|
+
Data_Get_Struct(self, git_object, object);
|
367
|
+
|
368
|
+
return rugged_raw_read(git_object_owner(object), git_object_id(object));
|
369
|
+
}
|
370
|
+
|
371
|
+
void Init_rugged_object(void)
|
372
|
+
{
|
373
|
+
rb_cRuggedObject = rb_define_class_under(rb_mRugged, "Object", rb_cObject);
|
374
|
+
rb_define_singleton_method(rb_cRuggedObject, "lookup", rb_git_object_lookup, 2);
|
375
|
+
rb_define_singleton_method(rb_cRuggedObject, "rev_parse", rb_git_object_rev_parse, 2);
|
376
|
+
rb_define_singleton_method(rb_cRuggedObject, "rev_parse_oid", rb_git_object_rev_parse_oid, 2);
|
377
|
+
rb_define_singleton_method(rb_cRuggedObject, "new", rb_git_object_lookup, 2);
|
378
|
+
|
379
|
+
rb_define_method(rb_cRuggedObject, "read_raw", rb_git_object_read_raw, 0);
|
380
|
+
rb_define_method(rb_cRuggedObject, "==", rb_git_object_equal, 1);
|
381
|
+
rb_define_method(rb_cRuggedObject, "oid", rb_git_object_oid_GET, 0);
|
382
|
+
rb_define_method(rb_cRuggedObject, "type", rb_git_object_type_GET, 0);
|
383
|
+
}
|