Ejemplo n.º 1
0
/**
 * ggit_ref_is_branch:
 * @ref: a #GgitRef.
 *
 * Check whether the reference is a branch.
 *
 * Returns: %TRUE if the reference is a branch, %FALSE otherwise.
 *
 **/
gboolean
ggit_ref_is_branch (GgitRef *ref)
{
	g_return_val_if_fail (ref != NULL, FALSE);

	return git_reference_is_branch (_ggit_native_get (ref));
}
Ejemplo n.º 2
0
int git_branch_is_head(
		const git_reference *branch)
{
	git_reference *head;
	bool is_same = false;
	int error;

	assert(branch);

	if (!git_reference_is_branch(branch))
		return false;

	error = git_repository_head(&head, git_reference_owner(branch));

	if (error == GIT_EUNBORNBRANCH || error == GIT_ENOTFOUND)
		return false;

	if (error < 0)
		return -1;

	is_same = strcmp(
		git_reference_name(branch),
		git_reference_name(head)) == 0;

	git_reference_free(head);

	return is_same;
}
Ejemplo n.º 3
0
static int retrieve_remote_tracking_reference(git_reference **base_ref, const char *identifier, git_repository *repo)
{
	git_reference *tracking, *ref;
	int error = -1;

	if (*base_ref == NULL) {
		if ((error = git_reference_dwim(&ref, repo, identifier)) < 0)
			return error;
	} else {
		ref = *base_ref;
		*base_ref = NULL;
	}

	if (!git_reference_is_branch(ref)) {
		error = GIT_EINVALIDSPEC;
		goto cleanup;
	}

	if ((error = git_branch_upstream(&tracking, ref)) < 0)
		goto cleanup;

	*base_ref = tracking;

cleanup:
	git_reference_free(ref);
	return error;
}
Ejemplo n.º 4
0
int git_branch_is_head(
		git_reference *branch)
{
	git_reference *head;
	bool is_same = false;
	int error;

	assert(branch);

	if (!git_reference_is_branch(branch))
		return false;

	error = git_repository_head(&head, git_reference_owner(branch));

	if (error == GIT_EORPHANEDHEAD)
		return false;

	if (error < 0)
		return -1;

	is_same = strcmp(
		git_reference_name(branch),
		git_reference_name(head)) == 0;

	git_reference_free(head);

	return is_same;
}
Ejemplo n.º 5
0
GgitRef *
_ggit_ref_wrap (git_reference *ref,
                gboolean       owned)
{
	GgitRef *gref;

	if (git_reference_is_branch (ref))
	{
		gref = GGIT_REF (_ggit_branch_wrap (ref));
	}
	else
	{
		gref = g_object_new (GGIT_TYPE_REF,
		                     "native", ref,
		                     NULL);
	}

	if (owned)
	{
		_ggit_native_set_destroy_func (gref,
		                               (GDestroyNotify)git_reference_free);
	}

	return gref;
}
Ejemplo n.º 6
0
static void assert_is_branch(const char *name, bool expected_branchness)
{
	git_reference *reference;
	cl_git_pass(git_reference_lookup(&reference, g_repo, name));
	cl_assert_equal_i(expected_branchness, git_reference_is_branch(reference));
	git_reference_free(reference);
}
Ejemplo n.º 7
0
/**
 * Get head of repository
 *
 * @param repo S4 class git_repository
 * @return R_NilValue if unborn branch or not found. S4 class
 * git_branch if not a detached head. S4 class git_commit if detached
 * head
 */
SEXP git2r_repository_head(SEXP repo)
{
    int err;
    SEXP result = R_NilValue;
    git_commit *commit = NULL;
    git_reference *reference = NULL;
    git_repository *repository = NULL;

    repository= git2r_repository_open(repo);
    if (!repository)
        git2r_error(git2r_err_invalid_repository, __func__, NULL);

    err = git_repository_head(&reference, repository);
    if (GIT_OK != err) {
        if (GIT_EUNBORNBRANCH == err || GIT_ENOTFOUND == err)
            err = GIT_OK;
        goto cleanup;
    }

    if (git_reference_is_branch(reference)) {
        git_branch_t type = GIT_BRANCH_LOCAL;
        if (git_reference_is_remote(reference))
            type = GIT_BRANCH_REMOTE;
        PROTECT(result = NEW_OBJECT(MAKE_CLASS("git_branch")));
        err = git2r_branch_init(reference, type, repo, result);
    } else {
        err = git_commit_lookup(
            &commit,
            repository,
            git_reference_target(reference));
        if (GIT_OK != err)
            goto cleanup;
        PROTECT(result = NEW_OBJECT(MAKE_CLASS("git_commit")));
        git2r_commit_init(commit, repo, result);
    }

cleanup:
    if (commit)
        git_commit_free(commit);

    if (reference)
        git_reference_free(reference);

    if (repository)
        git_repository_free(repository);

    if (R_NilValue != result)
        UNPROTECT(1);

    if (GIT_OK != err)
        git2r_error(git2r_err_from_libgit2, __func__, giterr_last()->message);

    return result;
}
Ejemplo n.º 8
0
int git_branch_move(
	git_reference **out,
	git_reference *branch,
	const char *new_branch_name,
	int force)
{
	git_buf new_reference_name = GIT_BUF_INIT,
	        old_config_section = GIT_BUF_INIT,
	        new_config_section = GIT_BUF_INIT,
	        log_message = GIT_BUF_INIT;
	int error;

	assert(branch && new_branch_name);

	if (!git_reference_is_branch(branch))
		return not_a_local_branch(git_reference_name(branch));

	if ((error = git_buf_joinpath(&new_reference_name, GIT_REFS_HEADS_DIR, new_branch_name)) < 0)
		goto done;

	if ((error = git_buf_printf(&log_message, "branch: renamed %s to %s",
				    git_reference_name(branch), git_buf_cstr(&new_reference_name))) < 0)
			goto done;

	/* first update ref then config so failure won't trash config */

	error = git_reference_rename(
		out, branch, git_buf_cstr(&new_reference_name), force,
		git_buf_cstr(&log_message));
	if (error < 0)
		goto done;

	git_buf_join(&old_config_section, '.', "branch",
		git_reference_name(branch) + strlen(GIT_REFS_HEADS_DIR));
	git_buf_join(&new_config_section, '.', "branch", new_branch_name);

	error = git_config_rename_section(
		git_reference_owner(branch),
		git_buf_cstr(&old_config_section),
		git_buf_cstr(&new_config_section));

done:
	git_buf_free(&new_reference_name);
	git_buf_free(&old_config_section);
	git_buf_free(&new_config_section);
	git_buf_free(&log_message);

	return error;
}
Ejemplo n.º 9
0
int git_branch_tracking(
		git_reference **tracking_out,
		git_reference *branch)
{
	const char *remote_name, *merge_name;
	git_buf buf = GIT_BUF_INIT;
	int error = -1;
	git_remote *remote = NULL;
	const git_refspec *refspec;

	assert(tracking_out && branch);

	if (!git_reference_is_branch(branch))
		return not_a_local_branch(branch);

	if ((error = retrieve_tracking_configuration(&remote_name, branch, "branch.%s.remote")) < 0)
		goto cleanup;

	if ((error = retrieve_tracking_configuration(&merge_name, branch, "branch.%s.merge")) < 0)
		goto cleanup;

	if (strcmp(".", remote_name) != 0) {
		if ((error = git_remote_load(&remote, git_reference_owner(branch), remote_name)) < 0)
			goto cleanup;

		refspec = git_remote_fetchspec(remote);
		if (refspec == NULL
			|| refspec->src == NULL
			|| refspec->dst == NULL) {
				error = GIT_ENOTFOUND;
				goto cleanup;
		}

		if (git_refspec_transform_r(&buf, refspec, merge_name) < 0)
			goto cleanup;
	} else
		if (git_buf_sets(&buf, merge_name) < 0)
			goto cleanup;

	error = git_reference_lookup(
		tracking_out,
		git_reference_owner(branch),
		git_buf_cstr(&buf));

cleanup:
	git_remote_free(remote);
	git_buf_free(&buf);
	return error;
}
Ejemplo n.º 10
0
int git_branch_move(
	git_reference *branch,
	const char *new_branch_name,
	int force)
{
	git_buf new_reference_name = GIT_BUF_INIT,
		old_config_section = GIT_BUF_INIT,
		new_config_section = GIT_BUF_INIT;
	int error;

	assert(branch && new_branch_name);

	if (!git_reference_is_branch(branch))
		return not_a_local_branch(branch);

	if ((error = git_buf_joinpath(&new_reference_name, GIT_REFS_HEADS_DIR, new_branch_name)) < 0)
		goto cleanup;

	if (git_buf_printf(
		&old_config_section,
		"branch.%s",
		git_reference_name(branch) + strlen(GIT_REFS_HEADS_DIR)) < 0)
			goto cleanup;

	if ((error = git_reference_rename(branch, git_buf_cstr(&new_reference_name), force)) < 0)
		goto cleanup;

	if (git_buf_printf(&new_config_section, "branch.%s", new_branch_name) < 0)
		goto cleanup;

	if ((error = git_config_rename_section(
		git_reference_owner(branch), 
		git_buf_cstr(&old_config_section),
		git_buf_cstr(&new_config_section))) < 0)
			goto cleanup;

cleanup:
	git_buf_free(&new_reference_name);
	git_buf_free(&old_config_section);
	git_buf_free(&new_config_section);

	return error;
}
int git_branch_name(const char **out, git_reference *ref)
{
	const char *branch_name;

	assert(out && ref);

	branch_name = ref->name;

	if (git_reference_is_branch(ref)) {
		branch_name += strlen(GIT_REFS_HEADS_DIR);
	} else if (git_reference_is_remote(ref)) {
		branch_name += strlen(GIT_REFS_REMOTES_DIR);
	} else {
		giterr_set(GITERR_INVALID,
				"Reference '%s' is neither a local nor a remote branch.", ref->name);
		return -1;
	}
	*out = branch_name;
	return 0;
}
int git_branch_delete(git_reference *branch)
{
	int is_head;
	git_buf config_section = GIT_BUF_INIT;
	int error = -1;

	assert(branch);

	if (!git_reference_is_branch(branch) &&
		!git_reference_is_remote(branch)) {
		giterr_set(GITERR_INVALID, "Reference '%s' is not a valid branch.", git_reference_name(branch));
		return -1;
	}

	if ((is_head = git_branch_is_head(branch)) < 0)
		return is_head;

	if (is_head) {
		giterr_set(GITERR_REFERENCE,
				"Cannot delete branch '%s' as it is the current HEAD of the repository.", git_reference_name(branch));
		return -1;
	}

	if (git_buf_printf(&config_section, "branch.%s", git_reference_name(branch) + strlen(GIT_REFS_HEADS_DIR)) < 0)
		goto on_error;

	if (git_config_rename_section(
		git_reference_owner(branch), 
		git_buf_cstr(&config_section),
		NULL) < 0)
			goto on_error;

	if (git_reference_delete(branch) < 0)
		goto on_error;

	error = 0;

on_error:
	git_buf_free(&config_section);
	return error;
}
Ejemplo n.º 13
0
/*
 *  call-seq:
 *    reference.branch? -> true or false
 *
 *  Returns +true+ if +reference+ is a local branch, false otherwise.
 */
static VALUE rb_git_ref_is_branch(VALUE self)
{
	git_reference *ref;
	Data_Get_Struct(self, git_reference, ref);
	return git_reference_is_branch(ref) ? Qtrue : Qfalse;
}