rdavila-rugged 0.24.0b13
Sign up to get free protection for your applications and to get access to all the features.
- 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,638 @@
|
|
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
|
+
#include <ctype.h>
|
27
|
+
#include <git2/sys/hashsig.h>
|
28
|
+
|
29
|
+
extern VALUE rb_mRugged;
|
30
|
+
extern VALUE rb_cRuggedObject;
|
31
|
+
extern VALUE rb_cRuggedRepo;
|
32
|
+
static ID id_read;
|
33
|
+
|
34
|
+
VALUE rb_cRuggedBlob;
|
35
|
+
VALUE rb_cRuggedBlobSig;
|
36
|
+
|
37
|
+
/*
|
38
|
+
* call-seq:
|
39
|
+
* blob.text(max_lines = -1, encoding = Encoding.default_external) -> string
|
40
|
+
*
|
41
|
+
* Return up to +max_lines+ of text from a blob as a +String+.
|
42
|
+
* If +max_lines+ is less than 0, the full string is returned.
|
43
|
+
*
|
44
|
+
* The string is created with the given +encoding+, defaulting to
|
45
|
+
* Encoding.default_external.
|
46
|
+
*
|
47
|
+
* When limiting the size of the text with +max_lines+, the string is
|
48
|
+
* expected to have an ASCII-compatible encoding, and is checked
|
49
|
+
* for the newline +\n+ character.
|
50
|
+
*/
|
51
|
+
static VALUE rb_git_blob_text_GET(int argc, VALUE *argv, VALUE self)
|
52
|
+
{
|
53
|
+
git_blob *blob;
|
54
|
+
size_t size;
|
55
|
+
const char *content;
|
56
|
+
VALUE rb_max_lines, rb_encoding;
|
57
|
+
|
58
|
+
Data_Get_Struct(self, git_blob, blob);
|
59
|
+
rb_scan_args(argc, argv, "02", &rb_max_lines, &rb_encoding);
|
60
|
+
|
61
|
+
content = git_blob_rawcontent(blob);
|
62
|
+
size = git_blob_rawsize(blob);
|
63
|
+
|
64
|
+
if (!NIL_P(rb_max_lines)) {
|
65
|
+
size_t i = 0;
|
66
|
+
int lines = 0, maxlines;
|
67
|
+
|
68
|
+
Check_Type(rb_max_lines, T_FIXNUM);
|
69
|
+
maxlines = FIX2INT(rb_max_lines);
|
70
|
+
|
71
|
+
if (maxlines >= 0) {
|
72
|
+
while (i < size && lines < maxlines) {
|
73
|
+
if (content[i++] == '\n')
|
74
|
+
lines++;
|
75
|
+
}
|
76
|
+
size = (size_t)i;
|
77
|
+
}
|
78
|
+
|
79
|
+
}
|
80
|
+
|
81
|
+
if (!NIL_P(rb_encoding)) {
|
82
|
+
return rb_enc_str_new(content, size, rb_to_encoding(rb_encoding));
|
83
|
+
}
|
84
|
+
|
85
|
+
return rb_external_str_new(content, size);
|
86
|
+
}
|
87
|
+
|
88
|
+
/*
|
89
|
+
* call-seq:
|
90
|
+
* blob.content(max_bytes=-1) -> string
|
91
|
+
*
|
92
|
+
* Return up to +max_bytes+ from the contents of a blob as bytes +String+.
|
93
|
+
* If +max_bytes+ is less than 0, the full string is returned.
|
94
|
+
*
|
95
|
+
* This string is tagged with the ASCII-8BIT encoding: the bytes are
|
96
|
+
* returned as-is, since Git is encoding agnostic.
|
97
|
+
*/
|
98
|
+
static VALUE rb_git_blob_content_GET(int argc, VALUE *argv, VALUE self)
|
99
|
+
{
|
100
|
+
git_blob *blob;
|
101
|
+
size_t size;
|
102
|
+
const char *content;
|
103
|
+
VALUE rb_max_bytes;
|
104
|
+
|
105
|
+
Data_Get_Struct(self, git_blob, blob);
|
106
|
+
rb_scan_args(argc, argv, "01", &rb_max_bytes);
|
107
|
+
|
108
|
+
content = git_blob_rawcontent(blob);
|
109
|
+
size = git_blob_rawsize(blob);
|
110
|
+
|
111
|
+
if (!NIL_P(rb_max_bytes)) {
|
112
|
+
int maxbytes;
|
113
|
+
|
114
|
+
Check_Type(rb_max_bytes, T_FIXNUM);
|
115
|
+
maxbytes = FIX2INT(rb_max_bytes);
|
116
|
+
|
117
|
+
if (maxbytes >= 0 && (size_t)maxbytes < size)
|
118
|
+
size = (size_t)maxbytes;
|
119
|
+
}
|
120
|
+
|
121
|
+
/*
|
122
|
+
* since we don't really ever know the encoding of a blob
|
123
|
+
* lets default to the binary encoding (ascii-8bit)
|
124
|
+
*/
|
125
|
+
return rb_str_new(content, size);
|
126
|
+
}
|
127
|
+
|
128
|
+
/*
|
129
|
+
* call-seq:
|
130
|
+
* blob.rawsize -> int
|
131
|
+
*
|
132
|
+
* Return the size in bytes of the blob. This is the real,
|
133
|
+
* uncompressed size and the length of +blob.content+, not
|
134
|
+
* the compressed size.
|
135
|
+
*/
|
136
|
+
static VALUE rb_git_blob_rawsize(VALUE self)
|
137
|
+
{
|
138
|
+
git_blob *blob;
|
139
|
+
Data_Get_Struct(self, git_blob, blob);
|
140
|
+
|
141
|
+
return INT2FIX(git_blob_rawsize(blob));
|
142
|
+
}
|
143
|
+
|
144
|
+
/*
|
145
|
+
* call-seq:
|
146
|
+
* Blob.from_buffer(repository, buffer) -> oid
|
147
|
+
*
|
148
|
+
* Write a blob to +repository+ with the contents specified
|
149
|
+
* in +buffer+, where +buffer+ is a +String+.
|
150
|
+
* The encoding of +buffer+ is ignored and bytes are copied as-is.
|
151
|
+
*/
|
152
|
+
static VALUE rb_git_blob_from_buffer(VALUE self, VALUE rb_repo, VALUE rb_buffer)
|
153
|
+
{
|
154
|
+
int error;
|
155
|
+
git_oid oid;
|
156
|
+
git_repository *repo;
|
157
|
+
|
158
|
+
Check_Type(rb_buffer, T_STRING);
|
159
|
+
rugged_check_repo(rb_repo);
|
160
|
+
|
161
|
+
Data_Get_Struct(rb_repo, git_repository, repo);
|
162
|
+
|
163
|
+
error = git_blob_create_frombuffer(&oid, repo, RSTRING_PTR(rb_buffer), RSTRING_LEN(rb_buffer));
|
164
|
+
rugged_exception_check(error);
|
165
|
+
|
166
|
+
return rugged_create_oid(&oid);
|
167
|
+
}
|
168
|
+
|
169
|
+
/*
|
170
|
+
* call-seq:
|
171
|
+
* Blob.from_workdir(repository, file_path) -> oid
|
172
|
+
*
|
173
|
+
* Write the file specified in +file_path+ to a blob in +repository+.
|
174
|
+
* +file_path+ must be relative to the repository's working folder.
|
175
|
+
* The repository cannot be bare.
|
176
|
+
*
|
177
|
+
* Blob.from_workdir(repo, 'src/blob.h') #=> '9d09060c850defbc7711d08b57def0d14e742f4e'
|
178
|
+
*/
|
179
|
+
static VALUE rb_git_blob_from_workdir(VALUE self, VALUE rb_repo, VALUE rb_path)
|
180
|
+
{
|
181
|
+
int error;
|
182
|
+
git_oid oid;
|
183
|
+
git_repository *repo;
|
184
|
+
|
185
|
+
Check_Type(rb_path, T_STRING);
|
186
|
+
rugged_check_repo(rb_repo);
|
187
|
+
|
188
|
+
Data_Get_Struct(rb_repo, git_repository, repo);
|
189
|
+
|
190
|
+
error = git_blob_create_fromworkdir(&oid, repo, StringValueCStr(rb_path));
|
191
|
+
rugged_exception_check(error);
|
192
|
+
|
193
|
+
return rugged_create_oid(&oid);
|
194
|
+
}
|
195
|
+
|
196
|
+
/*
|
197
|
+
* call-seq:
|
198
|
+
* Blob.from_disk(repository, file_path) -> oid
|
199
|
+
*
|
200
|
+
* Write the file specified in +file_path+ to a blob in +repository+.
|
201
|
+
* The repository can be bare or not.
|
202
|
+
*
|
203
|
+
* Example:
|
204
|
+
*
|
205
|
+
* Blob.from_disk(repo, '/var/repos/blob.h') #=> '5b5b025afb0b4c913b4c338a42934a3863bf3643'
|
206
|
+
*/
|
207
|
+
static VALUE rb_git_blob_from_disk(VALUE self, VALUE rb_repo, VALUE rb_path)
|
208
|
+
{
|
209
|
+
int error;
|
210
|
+
git_oid oid;
|
211
|
+
git_repository *repo;
|
212
|
+
|
213
|
+
Check_Type(rb_path, T_STRING);
|
214
|
+
rugged_check_repo(rb_repo);
|
215
|
+
|
216
|
+
Data_Get_Struct(rb_repo, git_repository, repo);
|
217
|
+
|
218
|
+
error = git_blob_create_fromdisk(&oid, repo, StringValueCStr(rb_path));
|
219
|
+
rugged_exception_check(error);
|
220
|
+
|
221
|
+
return rugged_create_oid(&oid);
|
222
|
+
}
|
223
|
+
|
224
|
+
static VALUE rb_read_check(VALUE pointer) {
|
225
|
+
VALUE *args = (VALUE *)pointer;
|
226
|
+
VALUE rb_buffer = rb_funcall(args[0], id_read, 1, args[1]);
|
227
|
+
|
228
|
+
if (!NIL_P(rb_buffer))
|
229
|
+
Check_Type(rb_buffer, T_STRING);
|
230
|
+
|
231
|
+
return rb_buffer;
|
232
|
+
}
|
233
|
+
|
234
|
+
static int cb_blob__get__chunk(char *content, size_t max_length, void *data)
|
235
|
+
{
|
236
|
+
VALUE rb_buffer, rb_args[2];
|
237
|
+
size_t str_len, safe_len;
|
238
|
+
struct rugged_cb_payload *payload = data;
|
239
|
+
|
240
|
+
rb_args[0] = payload->rb_data;
|
241
|
+
rb_args[1] = INT2FIX(max_length);
|
242
|
+
|
243
|
+
rb_buffer = rb_protect(rb_read_check, (VALUE)rb_args, &payload->exception);
|
244
|
+
|
245
|
+
if (payload->exception)
|
246
|
+
return GIT_ERROR;
|
247
|
+
|
248
|
+
if (NIL_P(rb_buffer))
|
249
|
+
return 0;
|
250
|
+
|
251
|
+
str_len = (size_t)RSTRING_LEN(rb_buffer);
|
252
|
+
safe_len = str_len > max_length ? max_length : str_len;
|
253
|
+
memcpy(content, StringValuePtr(rb_buffer), safe_len);
|
254
|
+
|
255
|
+
return (int)safe_len;
|
256
|
+
}
|
257
|
+
|
258
|
+
/*
|
259
|
+
* call-seq:
|
260
|
+
* Blob.from_io(repository, io [, hint_path]) -> oid
|
261
|
+
*
|
262
|
+
* Write a loose blob to the +repository+ from an +IO+ provider
|
263
|
+
* of data.
|
264
|
+
*
|
265
|
+
* The repository can be bare or not.
|
266
|
+
*
|
267
|
+
* The data provider +io+ should respond to a <code>read(size)</code>
|
268
|
+
* method. Generally any instance of a class based on Ruby's +IO+ class
|
269
|
+
* should work(ex. +File+). On each +read+ call it should
|
270
|
+
* return a +String+ with maximum size of +size+.
|
271
|
+
*
|
272
|
+
* *NOTE:* If an exception is raised in the +io+ object's
|
273
|
+
* +read+ method, no blob will be created.
|
274
|
+
*
|
275
|
+
* Provided the +hint_path+ parameter is given, its value
|
276
|
+
* will help to determine what git filters should be applied
|
277
|
+
* to the object before it can be placed to the object database.
|
278
|
+
*
|
279
|
+
* File.open('/path/to/file') do |file|
|
280
|
+
* Blob.from_io(repo, file, 'hint/blob.h') #=> '42cab3c0cde61e2b5a2392e1eadbeffa20ffa171'
|
281
|
+
* end
|
282
|
+
*/
|
283
|
+
static VALUE rb_git_blob_from_io(int argc, VALUE *argv, VALUE klass)
|
284
|
+
{
|
285
|
+
VALUE rb_repo, rb_io, rb_hint_path;
|
286
|
+
struct rugged_cb_payload payload;
|
287
|
+
const char * hint_path = NULL;
|
288
|
+
|
289
|
+
int error;
|
290
|
+
git_oid oid;
|
291
|
+
git_repository *repo;
|
292
|
+
|
293
|
+
rb_scan_args(argc, argv, "21", &rb_repo, &rb_io, &rb_hint_path);
|
294
|
+
|
295
|
+
rugged_check_repo(rb_repo);
|
296
|
+
Data_Get_Struct(rb_repo, git_repository, repo);
|
297
|
+
|
298
|
+
if (!NIL_P(rb_hint_path)) {
|
299
|
+
Check_Type(rb_hint_path, T_STRING);
|
300
|
+
hint_path = StringValueCStr(rb_hint_path);
|
301
|
+
}
|
302
|
+
|
303
|
+
payload.exception = 0;
|
304
|
+
payload.rb_data = rb_io;
|
305
|
+
|
306
|
+
error = git_blob_create_fromchunks(
|
307
|
+
&oid,
|
308
|
+
repo,
|
309
|
+
hint_path,
|
310
|
+
cb_blob__get__chunk,
|
311
|
+
(void *)&payload);
|
312
|
+
|
313
|
+
if (payload.exception)
|
314
|
+
rb_jump_tag(payload.exception);
|
315
|
+
rugged_exception_check(error);
|
316
|
+
|
317
|
+
return rugged_create_oid(&oid);
|
318
|
+
}
|
319
|
+
|
320
|
+
/*
|
321
|
+
* call-seq:
|
322
|
+
* blob.loc -> int
|
323
|
+
*
|
324
|
+
* Return the number of lines for this blob,
|
325
|
+
* assuming the blob is plaintext (i.e. not binary)
|
326
|
+
*/
|
327
|
+
static VALUE rb_git_blob_loc(VALUE self)
|
328
|
+
{
|
329
|
+
git_blob *blob;
|
330
|
+
const char *data, *data_end;
|
331
|
+
size_t loc = 0;
|
332
|
+
|
333
|
+
Data_Get_Struct(self, git_blob, blob);
|
334
|
+
|
335
|
+
data = git_blob_rawcontent(blob);
|
336
|
+
data_end = data + git_blob_rawsize(blob);
|
337
|
+
|
338
|
+
if (data == data_end)
|
339
|
+
return INT2FIX(0);
|
340
|
+
|
341
|
+
for (; data < data_end; ++data) {
|
342
|
+
if (data[0] == '\n') {
|
343
|
+
loc++;
|
344
|
+
}
|
345
|
+
else if (data[0] == '\r') {
|
346
|
+
if (data + 1 < data_end && data[1] == '\n')
|
347
|
+
data++;
|
348
|
+
loc++;
|
349
|
+
}
|
350
|
+
}
|
351
|
+
|
352
|
+
if (data[-1] != '\n' && data[-1] != '\r')
|
353
|
+
loc++;
|
354
|
+
|
355
|
+
return INT2FIX(loc);
|
356
|
+
}
|
357
|
+
|
358
|
+
|
359
|
+
/*
|
360
|
+
* call-seq:
|
361
|
+
* blob.sloc -> int
|
362
|
+
*
|
363
|
+
* Return the number of non-empty code lines for the blob,
|
364
|
+
* assuming the blob is plaintext (i.e. not binary)
|
365
|
+
*/
|
366
|
+
static VALUE rb_git_blob_sloc(VALUE self)
|
367
|
+
{
|
368
|
+
git_blob *blob;
|
369
|
+
const char *data, *data_end;
|
370
|
+
size_t sloc = 0;
|
371
|
+
|
372
|
+
Data_Get_Struct(self, git_blob, blob);
|
373
|
+
|
374
|
+
data = git_blob_rawcontent(blob);
|
375
|
+
data_end = data + git_blob_rawsize(blob);
|
376
|
+
|
377
|
+
if (data == data_end)
|
378
|
+
return INT2FIX(0);
|
379
|
+
|
380
|
+
/* go through the whole blob, counting lines
|
381
|
+
* that are not empty */
|
382
|
+
while (data < data_end) {
|
383
|
+
if (*data++ == '\n') {
|
384
|
+
while (data < data_end && isspace(*data))
|
385
|
+
data++;
|
386
|
+
|
387
|
+
sloc++;
|
388
|
+
}
|
389
|
+
}
|
390
|
+
|
391
|
+
/* last line without trailing '\n'? */
|
392
|
+
if (data[-1] != '\n')
|
393
|
+
sloc++;
|
394
|
+
|
395
|
+
return INT2FIX(sloc);
|
396
|
+
}
|
397
|
+
|
398
|
+
/*
|
399
|
+
* call-seq:
|
400
|
+
* blob.binary? -> true or false
|
401
|
+
*
|
402
|
+
* Determine if the blob content is most certainly binary or not.
|
403
|
+
*
|
404
|
+
* The heuristic used to guess if a file is binary is taken from core git:
|
405
|
+
* Searching for NUL bytes and looking for a reasonable ratio of printable
|
406
|
+
* to non-printable characters among the first 4000 bytes.
|
407
|
+
*
|
408
|
+
*/
|
409
|
+
static VALUE rb_git_blob_is_binary(VALUE self)
|
410
|
+
{
|
411
|
+
git_blob *blob;
|
412
|
+
Data_Get_Struct(self, git_blob, blob);
|
413
|
+
return git_blob_is_binary(blob) ? Qtrue : Qfalse;
|
414
|
+
}
|
415
|
+
|
416
|
+
/*
|
417
|
+
* call-seq:
|
418
|
+
* blob.diff(other, options = {}) -> patch
|
419
|
+
*
|
420
|
+
* Directly generate a Rugged::Patch from the difference between +blob+ and +other+.
|
421
|
+
*
|
422
|
+
* +other+ can either be another Rugged::Blob instance, a string,
|
423
|
+
* or nil (treated as an empty blob).
|
424
|
+
*
|
425
|
+
* The following options can be passed in the +options+ Hash:
|
426
|
+
*
|
427
|
+
* :max_size ::
|
428
|
+
* An integer specifying the maximum byte size of a blob before a it will
|
429
|
+
* be treated as binary. The default value is 512MB.
|
430
|
+
*
|
431
|
+
* :context_lines ::
|
432
|
+
* The number of unchanged lines that define the boundary of a hunk (and
|
433
|
+
* to display before and after the actual changes). The default is 3.
|
434
|
+
*
|
435
|
+
* :interhunk_lines ::
|
436
|
+
* The maximum number of unchanged lines between hunk boundaries before the hunks
|
437
|
+
* will be merged into a one. The default is 0.
|
438
|
+
*
|
439
|
+
* :reverse ::
|
440
|
+
* If true, the sides of the diff will be reversed.
|
441
|
+
*
|
442
|
+
* :force_text ::
|
443
|
+
* If true, all files will be treated as text, disabling binary attributes & detection.
|
444
|
+
*
|
445
|
+
* :ignore_whitespace ::
|
446
|
+
* If true, all whitespace will be ignored.
|
447
|
+
*
|
448
|
+
* :ignore_whitespace_change ::
|
449
|
+
* If true, changes in amount of whitespace will be ignored.
|
450
|
+
*
|
451
|
+
* :ignore_whitespace_eol ::
|
452
|
+
* If true, whitespace at end of line will be ignored.
|
453
|
+
*
|
454
|
+
* :patience ::
|
455
|
+
* If true, the "patience diff" algorithm will be used (currently unimplemented).
|
456
|
+
*
|
457
|
+
* :skip_binary_check ::
|
458
|
+
* If true, diff deltas will be generated without spending time on binary
|
459
|
+
* detection. This is useful to improve performance in cases where the actual
|
460
|
+
* file content difference is not needed.
|
461
|
+
*
|
462
|
+
* :old_path ::
|
463
|
+
* An optional string to treat +blob+ as if it had this filename.
|
464
|
+
*
|
465
|
+
* :new_path ::
|
466
|
+
* An optional string to treat +other+ as if it had this filename.
|
467
|
+
*/
|
468
|
+
static VALUE rb_git_blob_diff(int argc, VALUE *argv, VALUE self)
|
469
|
+
{
|
470
|
+
git_blob *blob;
|
471
|
+
git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
|
472
|
+
git_patch *patch;
|
473
|
+
const char *old_path = NULL, *new_path = NULL;
|
474
|
+
VALUE rb_other, rb_options;
|
475
|
+
int error;
|
476
|
+
|
477
|
+
rb_scan_args(argc, argv, "10:", &rb_other, &rb_options);
|
478
|
+
if (!NIL_P(rb_options)) {
|
479
|
+
VALUE rb_value;
|
480
|
+
|
481
|
+
rb_value = rb_hash_aref(rb_options, CSTR2SYM("old_path"));
|
482
|
+
if (!NIL_P(rb_value)) {
|
483
|
+
Check_Type(rb_value, T_STRING);
|
484
|
+
old_path = StringValueCStr(rb_value);
|
485
|
+
}
|
486
|
+
|
487
|
+
rb_value = rb_hash_aref(rb_options, CSTR2SYM("new_path"));
|
488
|
+
if (!NIL_P(rb_value)) {
|
489
|
+
Check_Type(rb_value, T_STRING);
|
490
|
+
new_path = StringValueCStr(rb_value);
|
491
|
+
}
|
492
|
+
|
493
|
+
rugged_parse_diff_options(&opts, rb_options);
|
494
|
+
}
|
495
|
+
|
496
|
+
Data_Get_Struct(self, git_blob, blob);
|
497
|
+
|
498
|
+
if (NIL_P(rb_other)) {
|
499
|
+
error = git_patch_from_blobs(&patch, blob, old_path, NULL, new_path, &opts);
|
500
|
+
} else if (rb_obj_is_kind_of(rb_other, rb_cRuggedBlob)) {
|
501
|
+
git_blob *other_blob;
|
502
|
+
|
503
|
+
Data_Get_Struct(rb_other, git_blob, other_blob);
|
504
|
+
|
505
|
+
error = git_patch_from_blobs(&patch, blob, old_path, other_blob, new_path, &opts);
|
506
|
+
} else if (TYPE(rb_other) == T_STRING) {
|
507
|
+
const char * buffer = StringValueCStr(rb_other);
|
508
|
+
|
509
|
+
error = git_patch_from_blob_and_buffer(&patch, blob, old_path, buffer, RSTRING_LEN(rb_other), new_path, &opts);
|
510
|
+
} else {
|
511
|
+
rb_raise(rb_eTypeError, "wrong argument type %s (expected Rugged::Blob, String, or nil)",
|
512
|
+
rb_obj_classname(rb_other));
|
513
|
+
}
|
514
|
+
|
515
|
+
rugged_exception_check(error);
|
516
|
+
|
517
|
+
return rugged_patch_new(self, patch);
|
518
|
+
}
|
519
|
+
|
520
|
+
static VALUE rb_git_blob_to_buffer(int argc, VALUE *argv, VALUE self)
|
521
|
+
{
|
522
|
+
VALUE rb_repo, rb_sha1, rb_max_bytes;
|
523
|
+
VALUE rb_ret;
|
524
|
+
|
525
|
+
git_repository *repo = NULL;
|
526
|
+
git_blob *blob = NULL;
|
527
|
+
|
528
|
+
size_t size;
|
529
|
+
const char *content;
|
530
|
+
|
531
|
+
rb_scan_args(argc, argv, "21", &rb_repo, &rb_sha1, &rb_max_bytes);
|
532
|
+
|
533
|
+
rugged_check_repo(rb_repo);
|
534
|
+
Data_Get_Struct(rb_repo, git_repository, repo);
|
535
|
+
|
536
|
+
blob = (git_blob *)rugged_object_get(repo, rb_sha1, GIT_OBJ_BLOB);
|
537
|
+
|
538
|
+
content = git_blob_rawcontent(blob);
|
539
|
+
size = git_blob_rawsize(blob);
|
540
|
+
|
541
|
+
if (!NIL_P(rb_max_bytes)) {
|
542
|
+
int maxbytes;
|
543
|
+
|
544
|
+
Check_Type(rb_max_bytes, T_FIXNUM);
|
545
|
+
maxbytes = FIX2INT(rb_max_bytes);
|
546
|
+
|
547
|
+
if (maxbytes >= 0 && (size_t)maxbytes < size)
|
548
|
+
size = (size_t)maxbytes;
|
549
|
+
}
|
550
|
+
|
551
|
+
rb_ret = rb_ary_new();
|
552
|
+
|
553
|
+
rb_ary_push(rb_ret, rb_str_new(content, size));
|
554
|
+
rb_ary_push(rb_ret, INT2FIX(git_blob_rawsize(blob)));
|
555
|
+
|
556
|
+
git_object_free((git_object*)blob);
|
557
|
+
|
558
|
+
/* TODO: LOC */
|
559
|
+
|
560
|
+
return rb_ret;
|
561
|
+
}
|
562
|
+
|
563
|
+
static VALUE rb_git_blob_sig_new(int argc, VALUE *argv, VALUE klass)
|
564
|
+
{
|
565
|
+
int error, opts = 0;
|
566
|
+
git_hashsig *sig;
|
567
|
+
VALUE rb_blob, rb_options;
|
568
|
+
|
569
|
+
if (rb_scan_args(argc, argv, "11", &rb_blob, &rb_options) == 2) {
|
570
|
+
Check_Type(rb_options, T_FIXNUM);
|
571
|
+
opts = FIX2INT(rb_options);
|
572
|
+
}
|
573
|
+
|
574
|
+
if (rb_obj_is_kind_of(rb_blob, rb_cRuggedBlob)) {
|
575
|
+
git_blob *blob;
|
576
|
+
Data_Get_Struct(rb_blob, git_blob, blob);
|
577
|
+
|
578
|
+
error = git_hashsig_create(&sig,
|
579
|
+
git_blob_rawcontent(blob),
|
580
|
+
git_blob_rawsize(blob),
|
581
|
+
opts);
|
582
|
+
} else {
|
583
|
+
Check_Type(rb_blob, T_STRING);
|
584
|
+
error = git_hashsig_create(&sig, RSTRING_PTR(rb_blob), RSTRING_LEN(rb_blob), opts);
|
585
|
+
}
|
586
|
+
|
587
|
+
rugged_exception_check(error);
|
588
|
+
|
589
|
+
return Data_Wrap_Struct(klass, NULL, &git_hashsig_free, sig);
|
590
|
+
}
|
591
|
+
|
592
|
+
static VALUE rb_git_blob_sig_compare(VALUE self, VALUE rb_sig_a, VALUE rb_sig_b)
|
593
|
+
{
|
594
|
+
git_hashsig *sig_a;
|
595
|
+
git_hashsig *sig_b;
|
596
|
+
int result;
|
597
|
+
|
598
|
+
if (!rb_obj_is_kind_of(rb_sig_a, rb_cRuggedBlobSig) ||
|
599
|
+
!rb_obj_is_kind_of(rb_sig_b, rb_cRuggedBlobSig)) {
|
600
|
+
rb_raise(rb_eTypeError, "Expected Rugged::Blob::HashSignature");
|
601
|
+
}
|
602
|
+
|
603
|
+
Data_Get_Struct(rb_sig_a, git_hashsig, sig_a);
|
604
|
+
Data_Get_Struct(rb_sig_b, git_hashsig, sig_b);
|
605
|
+
|
606
|
+
result = git_hashsig_compare(sig_a, sig_b);
|
607
|
+
|
608
|
+
if (result < 0)
|
609
|
+
rugged_exception_check(result);
|
610
|
+
|
611
|
+
return INT2FIX(result);
|
612
|
+
}
|
613
|
+
|
614
|
+
void Init_rugged_blob(void)
|
615
|
+
{
|
616
|
+
id_read = rb_intern("read");
|
617
|
+
|
618
|
+
rb_cRuggedBlob = rb_define_class_under(rb_mRugged, "Blob", rb_cRuggedObject);
|
619
|
+
|
620
|
+
rb_define_method(rb_cRuggedBlob, "size", rb_git_blob_rawsize, 0);
|
621
|
+
rb_define_method(rb_cRuggedBlob, "content", rb_git_blob_content_GET, -1);
|
622
|
+
rb_define_method(rb_cRuggedBlob, "text", rb_git_blob_text_GET, -1);
|
623
|
+
rb_define_method(rb_cRuggedBlob, "sloc", rb_git_blob_sloc, 0);
|
624
|
+
rb_define_method(rb_cRuggedBlob, "loc", rb_git_blob_loc, 0);
|
625
|
+
rb_define_method(rb_cRuggedBlob, "binary?", rb_git_blob_is_binary, 0);
|
626
|
+
rb_define_method(rb_cRuggedBlob, "diff", rb_git_blob_diff, -1);
|
627
|
+
|
628
|
+
rb_define_singleton_method(rb_cRuggedBlob, "from_buffer", rb_git_blob_from_buffer, 2);
|
629
|
+
rb_define_singleton_method(rb_cRuggedBlob, "from_workdir", rb_git_blob_from_workdir, 2);
|
630
|
+
rb_define_singleton_method(rb_cRuggedBlob, "from_disk", rb_git_blob_from_disk, 2);
|
631
|
+
rb_define_singleton_method(rb_cRuggedBlob, "from_io", rb_git_blob_from_io, -1);
|
632
|
+
|
633
|
+
rb_define_singleton_method(rb_cRuggedBlob, "to_buffer", rb_git_blob_to_buffer, -1);
|
634
|
+
|
635
|
+
rb_cRuggedBlobSig = rb_define_class_under(rb_cRuggedBlob, "HashSignature", rb_cObject);
|
636
|
+
rb_define_singleton_method(rb_cRuggedBlobSig, "new", rb_git_blob_sig_new, -1);
|
637
|
+
rb_define_singleton_method(rb_cRuggedBlobSig, "compare", rb_git_blob_sig_compare, 2);
|
638
|
+
}
|