Example #1
0
static VALUE reflog_entry_new(const git_reflog_entry *entry)
{
	VALUE rb_entry = rb_hash_new();
	const char *message;

	rb_hash_aset(rb_entry,
		CSTR2SYM("id_old"),
		rugged_create_oid(git_reflog_entry_id_old(entry))
	);

	rb_hash_aset(rb_entry,
		CSTR2SYM("id_new"),
		rugged_create_oid(git_reflog_entry_id_new(entry))
	);

	rb_hash_aset(rb_entry,
		CSTR2SYM("committer"),
		rugged_signature_new(git_reflog_entry_committer(entry), NULL)
	);

	if ((message = git_reflog_entry_message(entry)) != NULL) {
		rb_hash_aset(rb_entry, CSTR2SYM("message"), rb_str_new_utf8(message));
	}

	return rb_entry;
}
Example #2
0
static VALUE rugged_rhead_new(const git_remote_head *head)
{
	VALUE rb_head = rb_hash_new();

	rb_hash_aset(rb_head, CSTR2SYM("local?"), head->local ? Qtrue : Qfalse);
	rb_hash_aset(rb_head, CSTR2SYM("oid"), rugged_create_oid(&head->oid));
	rb_hash_aset(rb_head, CSTR2SYM("loid"),
			git_oid_iszero(&head->loid) ? Qnil : rugged_create_oid(&head->loid));
	rb_hash_aset(rb_head, CSTR2SYM("name"), rb_str_new_utf8(head->name));

	return rb_head;
}
Example #3
0
static VALUE rb_git_treeentry_fromC(const git_tree_entry *entry)
{
	VALUE rb_entry;
	VALUE type;

	if (!entry)
		return Qnil;

	rb_entry = rb_hash_new();

	rb_hash_aset(rb_entry, CSTR2SYM("name"), rugged_str_new2(git_tree_entry_name(entry), NULL));
	rb_hash_aset(rb_entry, CSTR2SYM("oid"), rugged_create_oid(git_tree_entry_id(entry)));

	rb_hash_aset(rb_entry, CSTR2SYM("filemode"), INT2FIX(git_tree_entry_filemode(entry)));

	switch(git_tree_entry_type(entry)) {
		case GIT_OBJ_TREE:
			type = CSTR2SYM("tree");
			break;

		case GIT_OBJ_BLOB:
			type = CSTR2SYM("blob");
			break;

		default:
			type = Qnil;
			break;
	}
	rb_hash_aset(rb_entry, CSTR2SYM("type"), type);

	return rb_entry;
}
Example #4
0
static VALUE rb_git_indexentry_fromC(const git_index_entry *entry)
{
	VALUE rb_entry, rb_mtime, rb_ctime;
	unsigned int valid, stage;

	if (!entry)
		return Qnil;

	rb_entry = rb_hash_new();

	rb_hash_aset(rb_entry, CSTR2SYM("path"), rb_str_new_utf8(entry->path));
	rb_hash_aset(rb_entry, CSTR2SYM("oid"), rugged_create_oid(&entry->id));

	rb_hash_aset(rb_entry, CSTR2SYM("dev"), INT2FIX(entry->dev));
	rb_hash_aset(rb_entry, CSTR2SYM("ino"), INT2FIX(entry->ino));
	rb_hash_aset(rb_entry, CSTR2SYM("mode"), INT2FIX(entry->mode));
	rb_hash_aset(rb_entry, CSTR2SYM("gid"), INT2FIX(entry->gid));
	rb_hash_aset(rb_entry, CSTR2SYM("uid"), INT2FIX(entry->uid));
	rb_hash_aset(rb_entry, CSTR2SYM("file_size"), INT2FIX(entry->file_size));

	valid = (entry->flags & GIT_IDXENTRY_VALID);
	rb_hash_aset(rb_entry, CSTR2SYM("valid"), valid ? Qtrue : Qfalse);

	stage = (entry->flags & GIT_IDXENTRY_STAGEMASK) >> GIT_IDXENTRY_STAGESHIFT;
	rb_hash_aset(rb_entry, CSTR2SYM("stage"), INT2FIX(stage));

	rb_mtime = rb_time_new(entry->mtime.seconds, entry->mtime.nanoseconds / 1000);
	rb_ctime = rb_time_new(entry->ctime.seconds, entry->ctime.nanoseconds / 1000);

	rb_hash_aset(rb_entry, CSTR2SYM("ctime"), rb_ctime);
	rb_hash_aset(rb_entry, CSTR2SYM("mtime"), rb_mtime);

	return rb_entry;
}
/*
 *  call-seq:
 *    Blob.from_chunks(repository, io [, hint_path]) -> oid
 *
 *  Write a loose blob to the +repository+ from a provider
 *  of chunks of data.
 *
 *  The repository can be bare or not.
 *
 *  The data provider +io+ should respond to a <code>read(size)</code>
 *  method. Generally any instance of a class based on Ruby's +IO+ class
 *  should work(ex. +File+). On each +read+ call it should
 *  return a +String+ with maximum size of +size+.
 *
 *  *NOTE:* If an exception is raised in the +io+ object's
 *  +read+ method, a blob will be created with the data up to that point
 *  and the exception will be rescued.
 *  It's recommended to compare the +blob.size+ with the expected data size
 *  to check if all the data was written.
 *
 *  Provided the +hint_path+ parameter is given, its value
 *  will help to determine what git filters should be applied
 *  to the object before it can be placed to the object database.
 *
 *    File.open('/path/to/file') do |file|
 *      Blob.from_chunks(repo, file, 'hint/blob.h') #=> '42cab3c0cde61e2b5a2392e1eadbeffa20ffa171'
 *    end
 */
static VALUE rb_git_blob_from_chunks(int argc, VALUE *argv, VALUE klass)
{
	VALUE rb_repo, rb_io, rb_hint_path;
	const char * hint_path = NULL;

	int error;
	git_oid oid;
	git_repository *repo;

	rb_scan_args(argc, argv, "21", &rb_repo, &rb_io, &rb_hint_path);

	rugged_check_repo(rb_repo);
	Data_Get_Struct(rb_repo, git_repository, repo);

	if (!NIL_P(rb_hint_path)) {
		Check_Type(rb_hint_path, T_STRING);
		hint_path = StringValueCStr(rb_hint_path);
	}

	error = git_blob_create_fromchunks(
			&oid,
			repo,
			hint_path,
			cb_blob__get__chunk,
			(void *)rb_io);

	rugged_exception_check(error);

	return rugged_create_oid(&oid);
}
Example #6
0
/*
 *  call-seq:
 *    Commit.create_with_signature(repo, content, signature, field_name = "gpgsig") -> oid
 *
 *  Create a commit from the +content+ string and the +signature+,
 *  adding this data to the +field_name+ header field in the resulting
 *  commit.
 *
 *  Returns the new commit's object id.
 *
 */
static VALUE rb_git_commit_create_with_signature(int argc, VALUE *argv, VALUE self)
{
	int error;
	git_oid id;
	const char *field = NULL;
	git_repository *repo;
	VALUE rb_repo, rb_content, rb_signature, rb_field = Qnil;

	rb_scan_args(argc, argv, "31", &rb_repo, &rb_content, &rb_signature, &rb_field);

	rugged_check_repo(rb_repo);
	Data_Get_Struct(rb_repo, git_repository, repo);

	Check_Type(rb_content, T_STRING);
	Check_Type(rb_signature, T_STRING);

	if (!NIL_P(rb_field)) {
		Check_Type(rb_field, T_STRING);
		field = StringValueCStr(rb_field);
	}

	error = git_commit_create_with_signature(&id, repo, StringValueCStr(rb_content), StringValueCStr(rb_signature), field);
	rugged_exception_check(error);

	return rugged_create_oid(&id);
}
static VALUE rugged_git_note_oid(const git_note* note)
{
	const git_oid *oid;
	oid = git_note_oid(note);

	return rugged_create_oid(oid);
}
Example #8
0
/*
 *  call-seq:
 *    Rebase.next() -> operation or nil
 *
 *  Perform the next step in the rebase. The returned operation is a
 *  Hash with its details or nil if there are no more operations to
 *  perform. The Hash contains some of the following entries:
 *
 *  :type ::
 *    The type of operation being done. Can be one of +:pick+,
 *    +:reword+, +:edit+, +:squash+, +:fixup+ or +:exec+.
 *
 *  :id ::
 *    The id of the commit being cherry-picked. Exists for all but
 *    +:exec+ operations.
 *
 *  :exec ::
 *    If the operatin is +:exec+ this is what the user asked to be
 *    executed.
 */
static VALUE rb_git_rebase_next(VALUE self)
{
	int error;
	git_rebase *rebase;
	git_rebase_operation *operation;
	VALUE hash, val;

	Data_Get_Struct(self, git_rebase, rebase);
	error = git_rebase_next(&operation, rebase);
	if (error == GIT_ITEROVER)
		return Qnil;

	rugged_exception_check(error);

	/* Create the operation hash out of the relevant details */
	hash = rb_hash_new();

	val = rebase_operation_type(operation);
	rb_hash_aset(hash, CSTR2SYM("type"), val);

	if (operation->type != GIT_REBASE_OPERATION_EXEC) {
		val = rugged_create_oid(&operation->id);
		rb_hash_aset(hash, CSTR2SYM("id"), val);
	}

	if (operation->exec) {
		val = rb_str_new_utf8(operation->exec);
		rb_hash_aset(hash, CSTR2SYM("exec"), val);
	}

	return hash;
}
Example #9
0
static int update_tips_cb(const char *refname, const git_oid *src, const git_oid *dest, void *data)
{
	struct rugged_remote_cb_payload *payload = data;
	VALUE args = rb_ary_new2(4);

	if (NIL_P(payload->update_tips))
		return 0;

	rb_ary_push(args, payload->update_tips);
	rb_ary_push(args, rb_str_new_utf8(refname));
	rb_ary_push(args, git_oid_iszero(src) ? Qnil : rugged_create_oid(src));
	rb_ary_push(args, git_oid_iszero(dest) ? Qnil : rugged_create_oid(dest));

	rb_protect(rugged__block_yield_splat, args, &payload->exception);

	return payload->exception ? GIT_ERROR : GIT_OK;
}
Example #10
0
/*
 *  call-seq:
 *    commit.tree_id -> oid
 *
 *  Return the tree oid pointed at by this +commit+. The tree is
 *  returned as a String object.
 *
 *    commit.tree_id #=> "f148106ca58764adc93ad4e2d6b1d168422b9796"
 */
static VALUE rb_git_commit_tree_id_GET(VALUE self)
{
	git_commit *commit;
	const git_oid *tree_id;

	Data_Get_Struct(self, git_commit, commit);

	tree_id = git_commit_tree_id(commit);

	return rugged_create_oid(tree_id);
}
Example #11
0
/*
 *  call-seq:
 *    annotation.target_oid -> oid
 *    annotation.target_id -> oid
 *
 *  Return the oid pointed at by this tag annotation, as a <tt>String</tt>
 *  instance.
 *
 *    annotation.target_id #=> "2cb831a8aea28b2c1b9c63385585b864e4d3bad1"
 */
static VALUE rb_git_tag_annotation_target_id(VALUE self)
{
	git_tag *tag;
	const git_oid *target_oid;

	Data_Get_Struct(self, git_tag, tag);

	target_oid = git_tag_target_id(tag);

	return rugged_create_oid(target_oid);
}
Example #12
0
/*
 *  call-seq:
 *    reference.target_id -> id
 *    reference.target_id -> ref_name
 *
 *  Return the target identifier of +reference+.
 *
 *  If +reference+ is a symbolic reference, it returns the canonical
 *  name of the target reference.
 *
 *  If +reference+ is a direct reference, it returns the sha id of the target.
 *
 *    ref1.type #=> :symbolic
 *    ref1.target_id #=> "refs/heads/master"
 *
 *    ref2.type #=> :direct
 *    ref2.target_id #=> "de5ba987198bcf2518885f0fc1350e5172cded78"
 */
static VALUE rb_git_ref_target_id(VALUE self)
{
	git_reference *ref;
	Data_Get_Struct(self, git_reference, ref);

	if (git_reference_type(ref) == GIT_REF_OID) {
		return rugged_create_oid(git_reference_target(ref));
	} else {
		return rb_str_new_utf8(git_reference_symbolic_target(ref));
	}
}
Example #13
0
/*
 *  call-seq:
 *    builder.write -> oid
 *
 *  Write +builder+'s content as a tree to the repository
 *  that owns the builder and return the +oid+ for the
 *  newly created tree.
 */
static VALUE rb_git_treebuilder_write(VALUE self)
{
	git_treebuilder *builder;
	git_oid written_id;
	int error;

	Data_Get_Struct(self, git_treebuilder, builder);

	error = git_treebuilder_write(&written_id, builder);
	rugged_exception_check(error);

	return rugged_create_oid(&written_id);
}
/*
 *  call-seq:
 *    Blob.from_disk(repository, file_path) -> oid
 *
 *  Write the file specified in +file_path+ to a blob in +repository+.
 *  The repository can be bare or not.
 *
 *  Example:
 *
 *    Blob.from_disk(repo, '/var/repos/blob.h') #=> '5b5b025afb0b4c913b4c338a42934a3863bf3643'
 */
static VALUE rb_git_blob_from_disk(VALUE self, VALUE rb_repo, VALUE rb_path)
{
	int error;
	git_oid oid;
	git_repository *repo;

	Check_Type(rb_path, T_STRING);
	rugged_check_repo(rb_repo);

	Data_Get_Struct(rb_repo, git_repository, repo);

	error = git_blob_create_fromdisk(&oid, repo, StringValueCStr(rb_path));
	rugged_exception_check(error);

	return rugged_create_oid(&oid);
}
/*
 *  call-seq:
 *    Blob.from_buffer(repository, bytes) -> oid
 *
 *  Write a blob to +repository+ with the contents specified
 *  in +buffer+. In Ruby 1.9.x, the encoding of +buffer+ is
 *  ignored and bytes are copied as-is.
 */
static VALUE rb_git_blob_from_buffer(VALUE self, VALUE rb_repo, VALUE rb_buffer)
{
	int error;
	git_oid oid;
	git_repository *repo;

	Check_Type(rb_buffer, T_STRING);
	rugged_check_repo(rb_repo);

	Data_Get_Struct(rb_repo, git_repository, repo);

	error = git_blob_create_frombuffer(&oid, repo, RSTRING_PTR(rb_buffer), RSTRING_LEN(rb_buffer));
	rugged_exception_check(error);

	return rugged_create_oid(&oid);
}
Example #16
0
/*
 *	call-seq:
 *		Blob.create(repository, bytes) -> oid
 *
 *	Write a blob to +repository+ with the contents specified
 *	in +buffer+. In Ruby 1.9.x, the encoding of +buffer+ is
 *	ignored and bytes are copied as-is.
 */
static VALUE rb_git_blob_create(VALUE self, VALUE rb_repo, VALUE rb_buffer)
{
	int error;
	git_oid oid;
	git_repository *repo;

	Check_Type(rb_buffer, T_STRING);
	if (!rb_obj_is_instance_of(rb_repo, rb_cRuggedRepo))
		rb_raise(rb_eTypeError, "Expecting a Rugged Repository");

	Data_Get_Struct(rb_repo, git_repository, repo);

	error = git_blob_create_frombuffer(&oid, repo, RSTRING_PTR(rb_buffer), RSTRING_LEN(rb_buffer));
	rugged_exception_check(error);

	return rugged_create_oid(&oid);
}
Example #17
0
/*
 *	call-seq:
 *		Blob.write_file(repository, file_path) -> oid
 *
 *	Write the file specified in +file_path+ to a blob in +repository+.
 *	+file_path+ must be relative to the repository's working folder.
 *
 *		Blob.write_file(repo, 'src/blob.h') #=> '9d09060c850defbc7711d08b57def0d14e742f4e'
 */
static VALUE rb_git_blob_writefile(VALUE self, VALUE rb_repo, VALUE rb_path)
{
	int error;
	git_oid oid;
	git_repository *repo;

	Check_Type(rb_path, T_STRING);
	if (!rb_obj_is_instance_of(rb_repo, rb_cRuggedRepo))
		rb_raise(rb_eTypeError, "Expecting a Rugged Repository");

	Data_Get_Struct(rb_repo, git_repository, repo);

	error = git_blob_create_fromfile(&oid, repo, StringValueCStr(rb_path));
	rugged_exception_check(error);

	return rugged_create_oid(&oid);
}
Example #18
0
VALUE rb_git_delta_file_fromC(const git_diff_file *file)
{
	VALUE rb_file;

	if (!file)
		return Qnil;

	rb_file = rb_hash_new();

	rb_hash_aset(rb_file, CSTR2SYM("oid"), rugged_create_oid(&file->id));
	rb_hash_aset(rb_file, CSTR2SYM("path"), file->path ? rb_str_new2(file->path) : Qnil);
	rb_hash_aset(rb_file, CSTR2SYM("size"), INT2FIX(file->size));
	rb_hash_aset(rb_file, CSTR2SYM("flags"), UINT2NUM(file->flags));
	rb_hash_aset(rb_file, CSTR2SYM("mode"), UINT2NUM(file->mode));

	return rb_file;
}
Example #19
0
static VALUE rb_git_treebuilder_write(VALUE self, VALUE rb_repo)
{
	git_treebuilder *builder;
	git_repository *repo;
	git_oid written_id;
	int error;

	if (!rb_obj_is_kind_of(rb_repo, rb_cRuggedRepo))
		rb_raise(rb_eTypeError, "Expecting a Rugged::Repository instance");

	Data_Get_Struct(self, git_treebuilder, builder);
	Data_Get_Struct(rb_repo, git_repository, repo);

	error = git_treebuilder_write(&written_id, repo, builder);
	rugged_exception_check(error);

	return rugged_create_oid(&written_id);
}
Example #20
0
/*
 *  call-seq:
 *    rebase.commit(author: nil, committer: committer, message: nil) -> oid or nil
 *
 *  Commit the current patch. Any conflicts must have been resolved.
 *
 *  If +author+ is +nil+, the existing author for the commit will be
 *  used. If +message+ is +nil+, the existing message will be used.
 *
 *  Returns a string containing the oid of the newly created commit,
 *  or +nil+ if there are no changes to be committed.
 */
static VALUE rb_git_rebase_commit(int argc, VALUE *argv, VALUE self)
{
	int error;
	git_oid id;
	git_rebase *rebase;
	git_signature *author = NULL, *committer;
	const char *message = NULL;
	VALUE rb_options, rb_author, rb_committer, rb_message;

	Data_Get_Struct(self, git_rebase, rebase);
	rb_scan_args(argc, argv, ":", &rb_options);

	Check_Type(rb_options, T_HASH);

	rb_author = rb_hash_aref(rb_options, CSTR2SYM("author"));
	rb_committer = rb_hash_aref(rb_options, CSTR2SYM("committer"));
	rb_message = rb_hash_aref(rb_options, CSTR2SYM("message"));

	if (!NIL_P(rb_message)) {
		Check_Type(rb_message, T_STRING);
		message = StringValueCStr(rb_message);
	}

	if (NIL_P(rb_committer))
		rb_raise(rb_eArgError, "Expected non-nil committer");
	else
		committer = rugged_signature_get(rb_committer, NULL);

	if (!NIL_P(rb_author))
		author = rugged_signature_get(rb_author, NULL);

	error = git_rebase_commit(&id, rebase, author, committer, NULL, message);
	git_signature_free(author);
	git_signature_free(committer);

	if (error == GIT_EAPPLIED) {
		giterr_clear();
		return Qnil;
	}

	rugged_exception_check(error);

	return rugged_create_oid(&id);
}
Example #21
0
/*
 *  call-seq:
 *    commit.parent_ids -> [oid, ...]
 *
 *  Return the parent oid(s) of this commit as an array of oid String
 *  objects. An array is always returned even when the commit has only
 *  one or zero parents.
 *
 *    commit.parent_ids #=> => ["2cb831a8aea28b2c1b9c63385585b864e4d3bad1", ...]
 *    root.parent_ids #=> []
 */
static VALUE rb_git_commit_parent_ids_GET(VALUE self)
{
	git_commit *commit;
	const git_oid *parent_id;
	unsigned int n, parent_count;
	VALUE ret_arr;

	Data_Get_Struct(self, git_commit, commit);

	parent_count = git_commit_parentcount(commit);
	ret_arr = rb_ary_new2((long)parent_count);

	for (n = 0; n < parent_count; n++) {
		parent_id = git_commit_parent_id(commit, n);
		if (parent_id) {
			rb_ary_push(ret_arr, rugged_create_oid(parent_id));
		}
	}

	return ret_arr;
}
Example #22
0
/*
 *  call-seq:
 *    index.write_tree([repo]) -> oid
 *
 *  Write the index to a tree, either in the index's repository, or in
 *  the given +repo+.
 *
 *  If the index contains any files in conflict, writing the tree will fail.
 *
 *  Returns the OID string of the written tree object.
 */
static VALUE rb_git_index_writetree(int argc, VALUE *argv, VALUE self)
{
	git_index *index;
	git_oid tree_oid;
	int error;
	VALUE rb_repo;

	Data_Get_Struct(self, git_index, index);

	if (rb_scan_args(argc, argv, "01", &rb_repo) == 1) {
		git_repository *repo = NULL;
		rugged_check_repo(rb_repo);
		Data_Get_Struct(rb_repo, git_repository, repo);
		error = git_index_write_tree_to(&tree_oid, index, repo);
	}
	else {
		error = git_index_write_tree(&tree_oid, index);
	}

	rugged_exception_check(error);
	return rugged_create_oid(&tree_oid);
}
Example #23
0
/*
 *  call-seq:
 *    Commit.create(repository, data = {}) -> oid
 *
 *  Write a new +Commit+ object to +repository+, with the given +data+
 *  arguments, passed as a +Hash+:
 *
 *  - +:message+: a string with the full text for the commit's message
 *  - +:committer+ (optional): a hash with the signature for the committer,
 *    defaults to the signature from the configuration
 *  - +:author+ (optional): a hash with the signature for the author,
 *    defaults to the signature from the configuration
 *  - +:parents+: an +Array+ with zero or more parents for this commit,
 *    represented as <tt>Rugged::Commit</tt> instances, or OID +String+.
 *  - +:tree+: the tree for this commit, represented as a <tt>Rugged::Tree</tt>
 *    instance or an OID +String+.
 *  - +:update_ref+ (optional): a +String+ with the name of a reference in the
 *    repository which should be updated to point to this commit (e.g. "HEAD")
 *
 *  When the commit is successfully written to disk, its +oid+ will be
 *  returned as a hex +String+.
 *
 *    author = {:email=>"*****@*****.**", :time=>Time.now, :name=>"Vicent Mart\303\255"}
 *
 *    Rugged::Commit.create(r,
 *      :author => author,
 *      :message => "Hello world\n\n",
 *      :committer => author,
 *      :parents => ["2cb831a8aea28b2c1b9c63385585b864e4d3bad1"],
 *      :tree => some_tree) #=> "f148106ca58764adc93ad4e2d6b1d168422b9796"
 */
static VALUE rb_git_commit_create(VALUE self, VALUE rb_repo, VALUE rb_data)
{
	int error = 0;
	struct commit_data commit_data = { Qnil };
	git_oid commit_oid;
	git_repository *repo;

	Check_Type(rb_data, T_HASH);

	rugged_check_repo(rb_repo);
	Data_Get_Struct(rb_repo, git_repository, repo);

	if ((error = parse_commit_options(&commit_data, repo, rb_data)) < 0)
		goto cleanup;

	error = git_commit_create(
		&commit_oid,
		repo,
		commit_data.update_ref,
		commit_data.author,
		commit_data.committer,
		NULL,
		commit_data.message,
		commit_data.tree,
		commit_data.parent_count,
		commit_data.parents);

cleanup:
	free_commit_options(&commit_data);
	if (!NIL_P(commit_data.rb_err_obj))
		rb_exc_raise(commit_data.rb_err_obj);

	rugged_exception_check(error);

	return rugged_create_oid(&commit_oid);
}
Example #24
0
/*
 *  call-seq:
 *    Commit.create(repository, data = {}) -> oid
 *
 *  Write a new +Commit+ object to +repository+, with the given +data+
 *  arguments, passed as a +Hash+:
 *
 *  - +:message+: a string with the full text for the commit's message
 *  - +:committer+ (optional): a hash with the signature for the committer,
 *    defaults to the signature from the configuration
 *  - +:author+ (optional): a hash with the signature for the author,
 *    defaults to the signature from the configuration
 *  - +:parents+: an +Array+ with zero or more parents for this commit,
 *    represented as <tt>Rugged::Commit</tt> instances, or OID +String+.
 *  - +:tree+: the tree for this commit, represented as a <tt>Rugged::Tree</tt>
 *    instance or an OID +String+.
 *  - +:update_ref+ (optional): a +String+ with the name of a reference in the
 *    repository which should be updated to point to this commit (e.g. "HEAD")
 *
 *  When the commit is successfully written to disk, its +oid+ will be
 *  returned as a hex +String+.
 *
 *    author = {:email=>"*****@*****.**", :time=>Time.now, :name=>"Vicent Mart\303\255"}
 *
 *    Rugged::Commit.create(r,
 *      :author => author,
 *      :message => "Hello world\n\n",
 *      :committer => author,
 *      :parents => ["2cb831a8aea28b2c1b9c63385585b864e4d3bad1"],
 *      :tree => some_tree) #=> "f148106ca58764adc93ad4e2d6b1d168422b9796"
 */
static VALUE rb_git_commit_create(VALUE self, VALUE rb_repo, VALUE rb_data)
{
	VALUE rb_message, rb_tree, rb_parents, rb_ref;
	VALUE rb_err_obj = Qnil;
	int parent_count, i, error = 0;
	const git_commit **parents = NULL;
	git_commit **free_list = NULL;
	git_tree *tree;
	git_signature *author, *committer;
	git_oid commit_oid;
	git_repository *repo;
	const char *update_ref = NULL;

	Check_Type(rb_data, T_HASH);

	rugged_check_repo(rb_repo);
	Data_Get_Struct(rb_repo, git_repository, repo);

	rb_ref = rb_hash_aref(rb_data, CSTR2SYM("update_ref"));
	if (!NIL_P(rb_ref)) {
		Check_Type(rb_ref, T_STRING);
		update_ref = StringValueCStr(rb_ref);
	}

	rb_message = rb_hash_aref(rb_data, CSTR2SYM("message"));
	Check_Type(rb_message, T_STRING);

	committer = rugged_signature_get(
		rb_hash_aref(rb_data, CSTR2SYM("committer")), repo
	);

	author = rugged_signature_get(
		rb_hash_aref(rb_data, CSTR2SYM("author")), repo
	);

	rb_parents = rb_hash_aref(rb_data, CSTR2SYM("parents"));
	Check_Type(rb_parents, T_ARRAY);

	rb_tree = rb_hash_aref(rb_data, CSTR2SYM("tree"));
	tree = (git_tree *)rugged_object_get(repo, rb_tree, GIT_OBJ_TREE);

	parents = alloca(RARRAY_LEN(rb_parents) * sizeof(void *));
	free_list = alloca(RARRAY_LEN(rb_parents) * sizeof(void *));
	parent_count = 0;

	for (i = 0; i < (int)RARRAY_LEN(rb_parents); ++i) {
		VALUE p = rb_ary_entry(rb_parents, i);
		git_commit *parent = NULL;
		git_commit *free_ptr = NULL;

		if (NIL_P(p))
			continue;

		if (TYPE(p) == T_STRING) {
			git_oid oid;

			error = git_oid_fromstr(&oid, StringValueCStr(p));
			if (error < GIT_OK)
				goto cleanup;

			error = git_commit_lookup(&parent, repo, &oid);
			if (error < GIT_OK)
				goto cleanup;

			free_ptr = parent;

		} else if (rb_obj_is_kind_of(p, rb_cRuggedCommit)) {
			Data_Get_Struct(p, git_commit, parent);
		} else {
			rb_err_obj = rb_exc_new2(rb_eTypeError, "Invalid type for parent object");
			goto cleanup;
		}

		parents[parent_count] = parent;
		free_list[parent_count] = free_ptr;
		parent_count++;
	}

	error = git_commit_create(
		&commit_oid,
		repo,
		update_ref,
		author,
		committer,
		NULL,
		StringValueCStr(rb_message),
		tree,
		parent_count,
		parents);

cleanup:
	git_signature_free(author);
	git_signature_free(committer);

	git_object_free((git_object *)tree);

	for (i = 0; i < parent_count; ++i)
		git_object_free((git_object *)free_list[i]);

	if (!NIL_P(rb_err_obj))
		rb_exc_raise(rb_err_obj);

	rugged_exception_check(error);

	return rugged_create_oid(&commit_oid);
}
/*
 *  call-seq:
 *    obj.create_note(data = {}) -> oid
 *
 *  Write a new +note+ to +object+, with the given +data+
 *  arguments, passed as a +Hash+:
 *
 *  - +:message+: the content of the note to add to the object
 *  - +:committer+: a hash with the signature for the committer
 *  - +:author+: a hash with the signature for the author
 *  - +:ref+: (optional): cannonical name of the reference to use, defaults to "refs/notes/commits"
 *  - +:force+: (optional): overwrite existing note (disabled by default)
 *
 *  When the note is successfully written to disk, its +oid+ will be
 *  returned as a hex +String+.
 *
 *    author = {:email=>"*****@*****.**", :time=>Time.now, :name=>"Vicent Mart\303\255"}
 *
 *    obj.create_note(
 *      :author    => author,
 *      :committer => author,
 *      :message   => "Hello world\n\n",
 *      :ref       => 'refs/notes/builds'
 *    )
 */
static VALUE rb_git_note_create(VALUE self, VALUE rb_data)
{
	VALUE rb_ref, rb_message, rb_force;
	git_repository *repo = NULL;
	const char *notes_ref = NULL;

	VALUE owner;

	git_signature *author, *committer;
	git_oid note_oid;

	git_object *target = NULL;
	int error = 0;
	int force = 0;

	Check_Type(rb_data, T_HASH);

	Data_Get_Struct(self, git_object, target);

	owner = rugged_owner(self);
	Data_Get_Struct(owner, git_repository, repo);

	rb_ref = rb_hash_aref(rb_data, CSTR2SYM("ref"));

	rb_force = rb_hash_aref(rb_data, CSTR2SYM("force"));
	if (!NIL_P(rb_force))
		force = rugged_parse_bool(rb_force);

	if (!NIL_P(rb_ref)) {
		Check_Type(rb_ref, T_STRING);
		notes_ref = StringValueCStr(rb_ref);
	}

	rb_message = rb_hash_aref(rb_data, CSTR2SYM("message"));
	Check_Type(rb_message, T_STRING);

	committer = rugged_signature_get(
		rb_hash_aref(rb_data, CSTR2SYM("committer"))
	);

	author = rugged_signature_get(
		rb_hash_aref(rb_data, CSTR2SYM("author"))
	);

	error = git_note_create(
			&note_oid,
			repo,
			author,
			committer,
			notes_ref,
			git_object_id(target),
			StringValueCStr(rb_message),
			force);


	git_signature_free(author);
	git_signature_free(committer);

	rugged_exception_check(error);

	return rugged_create_oid(&note_oid);
}
Example #26
0
/*
 *  call-seq:
 *    commit.amend(data = {}) -> oid
 *
 *  Amend a commit object, with the given +data+
 *  arguments, passed as a +Hash+:
 *
 *  - +:message+: a string with the full text for the commit's message
 *  - +:committer+ (optional): a hash with the signature for the committer,
 *    defaults to the signature from the configuration
 *  - +:author+ (optional): a hash with the signature for the author,
 *    defaults to the signature from the configuration
 *  - +:tree+: the tree for this amended commit, represented as a <tt>Rugged::Tree</tt>
 *    instance or an OID +String+.
 *  - +:update_ref+ (optional): a +String+ with the name of a reference in the
 *  repository which should be updated to point to this amended commit (e.g. "HEAD")
 *
 *  When the amended commit is successfully written to disk, its +oid+ will be
 *  returned as a hex +String+.
 *
 *    author = {:email=>"*****@*****.**", :time=>Time.now, :name=>"Vicent Mart\303\255"}
 *
 *    commit.amend(
 *      :author => author,
 *      :message => "Updated Hello world\n\n",
 *      :committer => author,
 *      :tree => some_tree) #=> "f148106ca58764adc93ad4e2d6b1d168422b9796"
 */
static VALUE rb_git_commit_amend(VALUE self, VALUE rb_data)
{
	VALUE rb_message, rb_tree, rb_ref, owner;
	int error = 0;
	git_commit *commit_to_amend;
	char *message = NULL;
	git_tree *tree = NULL;
	git_signature *author = NULL, *committer = NULL;
	git_oid commit_oid;
	git_repository *repo;
	const char *update_ref = NULL;

	Check_Type(rb_data, T_HASH);

	Data_Get_Struct(self, git_commit, commit_to_amend);

	owner = rugged_owner(self);
	Data_Get_Struct(owner, git_repository, repo);

	rb_ref = rb_hash_aref(rb_data, CSTR2SYM("update_ref"));
	if (!NIL_P(rb_ref)) {
		Check_Type(rb_ref, T_STRING);
		update_ref = StringValueCStr(rb_ref);
	}

	rb_message = rb_hash_aref(rb_data, CSTR2SYM("message"));
	if (!NIL_P(rb_message)) {
		Check_Type(rb_message, T_STRING);
		message = StringValueCStr(rb_message);
	}

	rb_tree = rb_hash_aref(rb_data, CSTR2SYM("tree"));
	if (!NIL_P(rb_tree))
		tree = (git_tree *)rugged_object_get(repo, rb_tree, GIT_OBJ_TREE);

	if (!NIL_P(rb_hash_aref(rb_data, CSTR2SYM("committer")))) {
		committer = rugged_signature_get(
			rb_hash_aref(rb_data, CSTR2SYM("committer")), repo
		);
	}

	if (!NIL_P(rb_hash_aref(rb_data, CSTR2SYM("author")))) {
		author = rugged_signature_get(
			rb_hash_aref(rb_data, CSTR2SYM("author")), repo
		);
	}

	error = git_commit_amend(
		&commit_oid,
		commit_to_amend,
		update_ref,
		author,
		committer,
		NULL,
		message,
		tree);

	git_signature_free(author);
	git_signature_free(committer);

	git_object_free((git_object *)tree);

	rugged_exception_check(error);

	return rugged_create_oid(&commit_oid);
}