14 static VALUE git_rb_object;
15 static VALUE git_rb_commit;
16 static VALUE git_rb_commit_list;
17 static VALUE git_rb_remote;
18 static VALUE git_rb_transport;
19 static VALUE git_rb_ref;
21 static inline VALUE sha1_to_str(const unsigned char *sha1)
23 return rb_str_new((const char *)sha1, 20);
26 static inline VALUE cstr_to_str(const char *str)
30 return rb_str_new2(str);
33 static inline char *str_to_cstr(VALUE str)
37 return RSTRING_PTR(str);
40 static inline unsigned char *str_to_sha1(VALUE str)
42 return (unsigned char *)str_to_cstr(str);
45 static VALUE git_rb_setup_git_directory(VALUE self)
49 prefix = setup_git_directory_gently(&nongit_ok);
50 return rb_ary_new3(2, cstr_to_str(prefix), INT2FIX(nongit_ok));
53 static int for_each_ref_fn(const char *refname, const unsigned char *sha1, int flags, void *cb_data)
56 r = rb_yield_values(3, rb_str_new2(refname), sha1_to_str(sha1), INT2FIX(flags));
60 static VALUE git_rb_for_each_ref(void)
63 r = for_each_ref(for_each_ref_fn, NULL);
67 static VALUE git_rb_dwim_ref(VALUE self, VALUE name)
69 unsigned char buf[20];
73 r = dwim_ref(RSTRING_PTR(name), RSTRING_LEN(name), buf, &ref);
74 return rb_ary_new3(3, sha1_to_str(buf), INT2NUM(r), cstr_to_str(ref));
77 static int git_config_fn(const char *var, const char *value, void *cb_data)
80 r = rb_yield_values(2, rb_str_new2(var), rb_str_new2(value));
84 static VALUE git_rb_git_config(VALUE self)
87 r = git_config(git_config_fn, NULL);
91 static VALUE git_rb_read_ref(VALUE self, VALUE refname)
93 unsigned char sha1[20];
94 if (read_ref(RSTRING_PTR(refname), sha1))
96 return sha1_to_str(sha1);
99 static VALUE git_rb_peel_ref(VALUE self, VALUE refname)
101 unsigned char sha1[20];
102 if (peel_ref(RSTRING_PTR(refname), sha1))
104 return sha1_to_str(sha1);
107 static VALUE git_rb_get_sha1(VALUE self, VALUE name)
109 unsigned char buf[20];
111 r = get_sha1(RSTRING_PTR(name), buf);
114 return sha1_to_str(buf);
117 static VALUE git_rb_object_get(VALUE class, VALUE id)
119 struct object *object;
120 object = parse_object(str_to_sha1(id));
121 return Data_Wrap_Struct(git_rb_object, NULL, NULL, object);
124 static VALUE git_rb_commit_get(VALUE class, VALUE id)
126 struct object *object;
127 object = parse_object(str_to_sha1(id));
128 if (!object || object->type != OBJ_COMMIT)
130 return Data_Wrap_Struct(git_rb_commit, NULL, NULL, object);
133 static VALUE git_rb_object_sha1(VALUE self)
135 struct object *object;
136 Data_Get_Struct(self, struct object, object);
137 return sha1_to_str(object->sha1);
140 static VALUE git_rb_object_type(VALUE self)
142 struct object *object;
143 Data_Get_Struct(self, struct object, object);
144 return INT2FIX(object->type);
147 static VALUE git_rb_object_to_s(VALUE self)
149 struct object *object;
150 Data_Get_Struct(self, struct object, object);
151 return rb_str_new2(sha1_to_hex(object->sha1));
154 static VALUE git_rb_commit_buffer(VALUE self)
156 struct commit *commit;
157 Data_Get_Struct(self, struct commit, commit);
158 return cstr_to_str(commit->buffer);
161 static VALUE git_rb_commit_list_each(VALUE self)
163 struct commit_list *e, *list;
164 Data_Get_Struct(self, struct commit_list, list);
166 for (e = list; e; e = e->next) {
168 c = Data_Wrap_Struct(git_rb_commit, NULL, NULL, e->item);
175 static VALUE git_rb_get_merge_bases(VALUE self, VALUE commits, VALUE cleanup)
177 struct commit *g_commits[RARRAY_LEN(commits)];
178 struct commit_list *result;
181 for (i = 0; i < RARRAY_LEN(commits); i++) {
182 VALUE commit = RARRAY_PTR(commits)[i];
183 Data_Get_Struct(commit, struct commit, g_commits[i]);
185 result = get_merge_bases_many(g_commits[0], RARRAY_LEN(commits) - 1, g_commits + 1, NUM2INT(cleanup));
188 return Data_Wrap_Struct(git_rb_commit_list, NULL, NULL, result);
191 static VALUE git_rb_remote_get(VALUE self, VALUE name)
193 struct remote *remote;
194 remote = remote_get(RSTRING_PTR(name));
197 return Data_Wrap_Struct(git_rb_remote, NULL, NULL, remote);
200 static VALUE git_rb_remote_url(VALUE self)
202 struct remote *remote;
206 Data_Get_Struct(self, struct remote, remote);
207 url = rb_ary_new2(remote->url_nr);
208 for (i = 0; i < remote->url_nr; i++)
209 rb_ary_store(url, i, rb_str_new2(remote->url[i]));
213 static VALUE git_rb_transport_get(VALUE self, VALUE remote, VALUE url)
215 struct transport *transport;
216 struct remote *g_remote;
217 Data_Get_Struct(remote, struct remote, g_remote);
218 transport = transport_get(g_remote, str_to_cstr(url));
221 return Data_Wrap_Struct(git_rb_transport, NULL, transport_disconnect, transport);
224 static VALUE git_rb_transport_get_remote_refs(VALUE self)
226 struct transport *transport;
227 const struct ref *ref;
228 Data_Get_Struct(self, struct transport, transport);
229 ref = transport_get_remote_refs(transport);
230 return Data_Wrap_Struct(git_rb_ref, NULL, NULL, (void *)ref);
233 static VALUE git_rb_ref_each(VALUE self)
236 Data_Get_Struct(self, struct ref, ref);
238 for (e = ref; e; e = e->next) {
240 c = Data_Wrap_Struct(git_rb_ref, NULL, NULL, e);
247 static VALUE git_rb_ref_name(VALUE self)
250 Data_Get_Struct(self, struct ref, ref);
251 return rb_str_new2(ref->name);
254 static VALUE git_rb_ref_old_sha1(VALUE self)
257 Data_Get_Struct(self, struct ref, ref);
258 return sha1_to_str(ref->old_sha1);
261 static VALUE git_rb_find_unique_abbrev(VALUE self, VALUE sha1, VALUE len)
264 abbrev = find_unique_abbrev(str_to_sha1(sha1), NUM2INT(len));
265 return rb_str_new2(abbrev);
268 static VALUE git_rb_read_sha1_file(VALUE self, VALUE sha1, VALUE type)
270 enum object_type g_type;
274 buffer = read_sha1_file(str_to_sha1(sha1), &g_type, &size);
277 return rb_ary_new3(2, rb_str_new(buffer, size), INT2FIX(g_type));
280 static void git_ruby_init(void)
284 mod = rb_define_module("Git");
286 rb_define_global_const("OBJ_BAD", INT2FIX(OBJ_BAD));
287 rb_define_global_const("OBJ_NONE", INT2FIX(OBJ_NONE));
288 rb_define_global_const("OBJ_COMMIT", INT2FIX(OBJ_COMMIT));
289 rb_define_global_const("OBJ_TREE", INT2FIX(OBJ_TREE));
290 rb_define_global_const("OBJ_BLOB", INT2FIX(OBJ_BLOB));
291 rb_define_global_const("OBJ_TAG", INT2FIX(OBJ_TAG));
292 rb_define_global_const("OBJ_OFS_DELTA", INT2FIX(OBJ_OFS_DELTA));
293 rb_define_global_const("OBJ_REF_DELTA", INT2FIX(OBJ_REF_DELTA));
294 rb_define_global_const("OBJ_ANY", INT2FIX(OBJ_ANY));
295 rb_define_global_const("OBJ_MAX", INT2FIX(OBJ_MAX));
297 rb_define_global_const("DEFAULT_ABBREV", INT2FIX(DEFAULT_ABBREV));
299 rb_define_global_function("setup_git_directory", git_rb_setup_git_directory, 0);
300 rb_define_global_function("for_each_ref", git_rb_for_each_ref, 0);
301 rb_define_global_function("dwim_ref", git_rb_dwim_ref, 1);
302 rb_define_global_function("git_config", git_rb_git_config, 0);
303 rb_define_global_function("read_ref", git_rb_read_ref, 1);
304 rb_define_global_function("peel_ref", git_rb_peel_ref, 1);
305 rb_define_global_function("get_sha1", git_rb_get_sha1, 1);
306 rb_define_global_function("get_merge_bases", git_rb_get_merge_bases, 2);
307 rb_define_global_function("remote_get", git_rb_remote_get, 1);
308 rb_define_global_function("transport_get", git_rb_transport_get, 2);
309 rb_define_global_function("find_unique_abbrev", git_rb_find_unique_abbrev, 2);
310 rb_define_global_function("read_sha1_file", git_rb_read_sha1_file, 1);
312 git_rb_object = rb_define_class_under(mod, "Object", rb_cData);
313 rb_define_singleton_method(git_rb_object, "get", git_rb_object_get, 1);
314 rb_define_method(git_rb_object, "sha1", git_rb_object_sha1, 0);
315 rb_define_method(git_rb_object, "type", git_rb_object_type, 0);
316 rb_define_method(git_rb_object, "to_s", git_rb_object_to_s, 0);
318 git_rb_commit = rb_define_class_under(mod, "Commit", git_rb_object);
319 rb_define_singleton_method(git_rb_commit, "get", git_rb_commit_get, 1);
320 rb_define_method(git_rb_commit, "buffer", git_rb_commit_buffer, 0);
322 git_rb_commit_list = rb_define_class_under(mod, "CommitList", rb_cData);
323 rb_include_module(git_rb_commit_list, rb_mEnumerable);
324 rb_define_method(git_rb_commit_list, "each", git_rb_commit_list_each, 0);
326 git_rb_remote = rb_define_class_under(mod, "Remote", rb_cData);
327 rb_define_method(git_rb_remote, "url", git_rb_remote_url, 0);
329 git_rb_transport = rb_define_class_under(mod, "Transport", rb_cData);
330 rb_define_method(git_rb_transport, "get_remote_refs", git_rb_transport_get_remote_refs, 0);
332 git_rb_ref = rb_define_class_under(mod, "Ref", rb_cData);
333 rb_include_module(git_rb_ref, rb_mEnumerable);
334 rb_define_method(git_rb_ref, "each", git_rb_ref_each, 0);
335 rb_define_method(git_rb_ref, "name", git_rb_ref_name, 0);
336 rb_define_method(git_rb_ref, "old_sha1", git_rb_ref_old_sha1, 0);
339 static int run_ruby_command(const char *cmd, int argc, const char **argv)
341 static char buf[PATH_MAX + 1];
348 node = ruby_options(argc, (char **)argv);
351 snprintf(buf, PATH_MAX, "%s/%s", git_exec_path(), "git-rb-setup.rb");
353 rb_load(rb_str_new2(buf), 0);
355 return ruby_run_node(node);
358 int main(int argc, const char **argv)
360 if (!strcmp(argv[0], "git-ruby")) {
361 return run_ruby_command(argv[1], argc, argv);
363 const char *cmd = argv[0];
364 static char buf[PATH_MAX + 1];
365 const char *args[argc + 1];
368 snprintf(buf, PATH_MAX, "%s/%s.rb",
369 git_exec_path(), basename((char *)cmd));
373 for (i = 0; i < argc - 1; i++)
374 args[i + 2] = (char *)argv[i + 1];
376 return run_ruby_command(cmd, argc + 1, args);