/*
 *  call-seq:
 *    branch.move(old_name, new_name, options = {}) -> new_branch
 *    branch.move(branch, new_name, options = {}) -> new_branch
 *    branch.rename(old_name, new_name, options = {}) -> new_branch
 *    branch.rename(branch, new_name, options = {}) -> new_branch
 *
 *  Rename a branch to +new_name+.
 *
 *  +new_name+ needs to be a branch name, not an absolute reference path
 *  (e.g. +development+ instead of +refs/heads/development+).
 *
 *  The following options can be passed in the +options+ Hash:
 *
 *  :force ::
 *    Overwrites the branch with the given +name+, if it already exists,
 *    instead of raising an exception.
 *
 *  If a branch with the given +new_name+ already exists and +:force+ is not +true+,
 *  an exception will be raised.
 *
 *  A new Rugged::Branch object for the renamed branch will be returned.
 *
 */
static VALUE rb_git_branch_collection_move(int argc, VALUE *argv, VALUE self)
{
	VALUE rb_repo = rugged_owner(self), rb_name_or_branch, rb_new_branch_name, rb_options;
	git_reference *old_branch = NULL, *new_branch = NULL;
	git_repository *repo;
	int error, force = 0;

	rb_scan_args(argc, argv, "20:", &rb_name_or_branch, &rb_new_branch_name, &rb_options);
	Check_Type(rb_new_branch_name, T_STRING);

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

	error = rugged_branch_lookup(&old_branch, repo, rb_name_or_branch);
	rugged_exception_check(error);

	if (!NIL_P(rb_options)) {
		force = RTEST(rb_hash_aref(rb_options, CSTR2SYM("force")));
	}

	error = git_branch_move(&new_branch, old_branch, StringValueCStr(rb_new_branch_name), force);

	git_reference_free(old_branch);

	rugged_exception_check(error);

	return rugged_branch_new(rugged_owner(self), new_branch);
}
/*
 *  call-seq:
 *    branches.create(name, target, options = {}) -> branch
 *
 *  Create a new branch with the given +name+, pointing to the +target+.
 *
 *  +name+ needs to be a branch name, not an absolute reference path
 *  (e.g. +development+ instead of +refs/heads/development+).
 *
 *  +target+ needs to be an existing commit in the given repository.
 *
 *  The following options can be passed in the +options+ Hash:
 *
 *  :force ::
 *    Overwrites the branch with the given +name+, if it already exists,
 *    instead of raising an exception.
 *
 *  If a branch with the given +name+ already exists and +:force+ is not +true+,
 *  an exception will be raised.
 *
 *  Returns a Rugged::Branch for the newly created branch.
 */
static VALUE rb_git_branch_collection_create(int argc, VALUE *argv, VALUE self)
{
	VALUE rb_repo = rugged_owner(self), rb_name, rb_target, rb_options;
	git_repository *repo;
	git_reference *branch;
	git_commit *target;
	int error, force = 0;

	rb_scan_args(argc, argv, "20:", &rb_name, &rb_target, &rb_options);

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

	Check_Type(rb_name, T_STRING);
	Check_Type(rb_target, T_STRING);

	if (!NIL_P(rb_options)) {
		force = RTEST(rb_hash_aref(rb_options, CSTR2SYM("force")));
	}

	target = (git_commit *)rugged_object_get(repo, rb_target, GIT_OBJ_COMMIT);

	error = git_branch_create(&branch, repo, StringValueCStr(rb_name), target, force);

	git_commit_free(target);

	rugged_exception_check(error);

	return rugged_branch_new(rb_repo, branch);
}
static VALUE each_branch(int argc, VALUE *argv, VALUE self, int branch_names_only)
{
	VALUE rb_repo = rugged_owner(self), rb_filter;
	git_repository *repo;
	git_branch_iterator *iter;
	int error, exception = 0;
	git_branch_t filter = (GIT_BRANCH_LOCAL | GIT_BRANCH_REMOTE), branch_type;

	rb_scan_args(argc, argv, "01", &rb_filter);

	if (!rb_block_given_p()) {
		VALUE symbol = branch_names_only ? CSTR2SYM("each_name") : CSTR2SYM("each");
		return rb_funcall(self, rb_intern("to_enum"), 2, symbol, rb_filter);
	}

	rugged_check_repo(rb_repo);

	if (!NIL_P(rb_filter))
		filter = parse_branch_type(rb_filter);

	Data_Get_Struct(rb_repo, git_repository, repo);

	error = git_branch_iterator_new(&iter, repo, filter);
	rugged_exception_check(error);

	if (branch_names_only) {
		git_reference *branch;
		while (!exception && (error = git_branch_next(&branch, &branch_type, iter)) == GIT_OK) {
			rb_protect(rb_yield, rb_str_new_utf8(git_reference_shorthand(branch)), &exception);
		}
	} else {
		git_reference *branch;
		while (!exception && (error = git_branch_next(&branch, &branch_type, iter)) == GIT_OK) {
			rb_protect(rb_yield, rugged_branch_new(rb_repo, branch), &exception);
		}
	}

	git_branch_iterator_free(iter);

	if (exception)
		rb_jump_tag(exception);

	if (error != GIT_ITEROVER)
		rugged_exception_check(error);

	return Qnil;
}
/*
 *  call-seq:
 *    branches[name] -> branch
 *
 *  Return the branch with the given +name+.
 *
 *  Branches can be looked up by their relative (+development+) or absolute
 *  (+refs/heads/development+) branch name.
 *
 *  If a local branch and a remote branch both share the same short name
 *  (e.g. +refs/heads/origin/master+ and +refs/remotes/origin/master+),
 *  passing +origin/master+ as the +name+ will return the local branch.
 *  You can explicitly request the local branch by passing
 *  +heads/origin/master+, or the remote branch through +remotes/origin/master+.
 *
 *  Returns the looked up branch, or +nil+ if the branch doesn't exist.
 */
static VALUE rb_git_branch_collection_aref(VALUE self, VALUE rb_name) {
	git_reference *branch;
	git_repository *repo;

	VALUE rb_repo = rugged_owner(self);
	int error;

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

	Check_Type(rb_name, T_STRING);

	error = rugged_branch_lookup(&branch, repo, rb_name);
	if (error == GIT_ENOTFOUND)
		return Qnil;

	rugged_exception_check(error);
	return rugged_branch_new(rb_repo, branch);
}
Example #5
0
/*
 *  call-seq:
 *    branch.upstream -> branch
 *
 *  Returns the remote tracking branch, or +nil+ if the branch is
 *  remote or has no tracking branch.
 */
static VALUE rb_git_branch_upstream(VALUE self)
{
	git_reference *branch, *upstream_branch;
	int error;

	Data_Get_Struct(self, git_reference, branch);

	if (git_reference_is_remote(branch))
		return Qnil;

	error = git_branch_upstream(&upstream_branch, branch);

	if (error == GIT_ENOTFOUND)
		return Qnil;

	rugged_exception_check(error);

	return rugged_branch_new(rugged_owner(self), upstream_branch);
}