Permalink
Browse files

Add Rugged::Diff#write_patch

  • Loading branch information...
brianmario committed Sep 12, 2012
1 parent 86a8603 commit 41e2d277b8dd637d264ddb053ac5842e848cd9b1
Showing with 36 additions and 0 deletions.
  1. +36 −0 ext/rugged/rugged_diff.c
View
@@ -27,6 +27,7 @@
extern VALUE rb_mRugged;
extern VALUE rb_cRuggedDiffFile;
VALUE rb_cRuggedDiff;
+static ID id_write;
static void rb_git_diff__free(rugged_diff *diff)
{
@@ -78,6 +79,38 @@ static VALUE rb_git_diff_patch_GET(VALUE self)
return str;
}
+static int diff_write_cb(void *data, git_diff_delta *delta, git_diff_range *range, char usage,
+ const char *line, size_t line_len)
+{
+ VALUE *io = data;
+ VALUE str;
+
+ str = rugged_str_new(line, line_len, NULL);

This comment has been minimized.

Show comment Hide comment
@vmg

vmg Sep 12, 2012

Owner

What happened to rb_io_write? I thought we were going to roll with that. Regardless, the global id_write is very ugly. We should stick to calling rb_intern locally.

@vmg

vmg Sep 12, 2012

Owner

What happened to rb_io_write? I thought we were going to roll with that. Regardless, the global id_write is very ugly. We should stick to calling rb_intern locally.

This comment has been minimized.

Show comment Hide comment
@brianmario

brianmario Sep 12, 2012

Member

Looking up id_write was just an optimization (the ruby-core code does this all over the place) but I can change it to looking it up each time.

As for rb_io_write, I decided to use rb_funcall because even though internally it's doing the same thing, that could change and end up doing something that will only work on IO objects. Waddya think?

@brianmario

brianmario Sep 12, 2012

Member

Looking up id_write was just an optimization (the ruby-core code does this all over the place) but I can change it to looking it up each time.

As for rb_io_write, I decided to use rb_funcall because even though internally it's doing the same thing, that could change and end up doing something that will only work on IO objects. Waddya think?

This comment has been minimized.

Show comment Hide comment
@arthurschreiber

arthurschreiber Sep 12, 2012

Member

I'd go with rb_io_write for now, and maybe add some tests where you write into a StringIO to make sure that we get notified if this behaviour ever changes.

@arthurschreiber

arthurschreiber Sep 12, 2012

Member

I'd go with rb_io_write for now, and maybe add some tests where you write into a StringIO to make sure that we get notified if this behaviour ever changes.

This comment has been minimized.

Show comment Hide comment
@brianmario

brianmario Sep 12, 2012

Member

@arthurschreiber that'll work :)

+ rb_funcall(*io, id_write, 1, str);
+
+ return 0;
+}
+
+/*
+ * call-seq:
+ * diff.write_patch(io)
+ *
+ * Write a patch directly to an object which responds to "write".
+ */
+static VALUE rb_git_diff_write_patch(VALUE self, VALUE io)
+{
+ rugged_diff *diff;
+
+ if (!rb_respond_to(io, id_write))
+ rb_raise(rb_eArgError, "Expected io to respond to \"write\"");
+
+ Data_Get_Struct(self, rugged_diff, diff);
+
+ git_diff_print_patch(diff->diff, &io, diff_write_cb);
+
+ return Qnil;
+}
+
static VALUE rb_git_diff_merge(VALUE self, VALUE rb_other)
{
rugged_diff *diff;
@@ -120,9 +153,12 @@ static VALUE rb_git_diff_each_delta(VALUE self)
void Init_rugged_diff()
{
+ id_write = rb_intern("write");
+
rb_cRuggedDiff = rb_define_class_under(rb_mRugged, "Diff", rb_cObject);
rb_define_method(rb_cRuggedDiff, "patch", rb_git_diff_patch_GET, 0);
+ rb_define_method(rb_cRuggedDiff, "write_patch", rb_git_diff_write_patch, 1);
rb_define_method(rb_cRuggedDiff, "merge!", rb_git_diff_merge, 1);
rb_define_method(rb_cRuggedDiff, "each_delta", rb_git_diff_each_delta, 0);
}

0 comments on commit 41e2d27

Please sign in to comment.