Example #1
0
void test_network_remote_defaultbranch__detached_sharing_nonbranch_id(void)
{
    git_oid id, id_cloned;
    git_reference *ref;
    git_buf buf = GIT_BUF_INIT;
    git_repository *cloned_repo;

    cl_git_pass(git_reference_name_to_id(&id, g_repo_a, "HEAD"));
    cl_git_pass(git_repository_detach_head(g_repo_a, NULL, NULL));
    cl_git_pass(git_reference_remove(g_repo_a, "refs/heads/master"));
    cl_git_pass(git_reference_remove(g_repo_a, "refs/heads/not-good"));
    cl_git_pass(git_reference_create(&ref, g_repo_a, "refs/foo/bar", &id, 1, NULL, NULL));
    git_reference_free(ref);

    cl_git_pass(git_remote_connect(g_remote, GIT_DIRECTION_FETCH));
    cl_git_fail_with(GIT_ENOTFOUND, git_remote_default_branch(&buf, g_remote));

    cl_git_pass(git_clone(&cloned_repo, git_repository_path(g_repo_a), "./local-detached", NULL));

    cl_assert(git_repository_head_detached(cloned_repo));
    cl_git_pass(git_reference_name_to_id(&id_cloned, g_repo_a, "HEAD"));
    cl_assert(git_oid_equal(&id, &id_cloned));

    git_repository_free(cloned_repo);
}
Example #2
0
static void assert_default_branch(const char *should)
{
    git_buf name = GIT_BUF_INIT;

    cl_git_pass(git_remote_connect(g_remote, GIT_DIRECTION_FETCH));
    cl_git_pass(git_remote_default_branch(&name, g_remote));
    cl_assert_equal_s(should, name.ptr);
    git_buf_free(&name);
}
Example #3
0
void test_network_remote_defaultbranch__no_default_branch(void)
{
    git_remote *remote_b;
    const git_remote_head **heads;
    size_t len;
    git_buf buf = GIT_BUF_INIT;

    cl_git_pass(git_remote_create(&remote_b, g_repo_b, "self", git_repository_path(g_repo_b)));
    cl_git_pass(git_remote_connect(remote_b, GIT_DIRECTION_FETCH));
    cl_git_pass(git_remote_ls(&heads, &len, remote_b));
    cl_assert_equal_i(0, len);

    cl_git_fail_with(GIT_ENOTFOUND, git_remote_default_branch(&buf, remote_b));

    git_remote_free(remote_b);
}
Example #4
0
static int update_head_to_remote(
		git_repository *repo,
		git_remote *remote,
		const git_signature *signature,
		const char *reflog_message)
{
	int error = 0, found_branch = 0;
	size_t refs_len;
	git_refspec dummy_spec, *refspec;
	const git_remote_head *remote_head, **refs;
	const git_oid *remote_head_id;
	git_buf remote_master_name = GIT_BUF_INIT;
	git_buf branch = GIT_BUF_INIT;

	if ((error = git_remote_ls(&refs, &refs_len, remote)) < 0)
		return error;

	/* Did we just clone an empty repository? */
	if (refs_len == 0)
		return setup_tracking_config(
			repo, "master", GIT_REMOTE_ORIGIN, GIT_REFS_HEADS_MASTER_FILE);

	error = git_remote_default_branch(&branch, remote);
	if (error == GIT_ENOTFOUND) {
		git_buf_puts(&branch, GIT_REFS_HEADS_MASTER_FILE);
	} else {
		found_branch = 1;
	}

	/* Get the remote's HEAD. This is always the first ref in the list. */
	remote_head = refs[0];
	assert(remote_head);

	remote_head_id = &remote_head->oid;
	refspec = git_remote__matching_refspec(remote, git_buf_cstr(&branch));

	if (refspec == NULL) {
		memset(&dummy_spec, 0, sizeof(git_refspec));
		refspec = &dummy_spec;
	}

	/* Determine the remote tracking reference name from the local master */
	if ((error = git_refspec_transform(
		&remote_master_name,
		refspec,
		git_buf_cstr(&branch))) < 0)
		return error;

	if (found_branch) {
		error = update_head_to_new_branch(
			repo,
			remote_head_id,
			git_buf_cstr(&branch),
			signature, reflog_message);
	} else {
		error = git_repository_set_head_detached(
			repo, remote_head_id, signature, reflog_message);
	}

	git_buf_free(&remote_master_name);
	git_buf_free(&branch);
	return error;
}
Example #5
0
static int update_head_to_remote(
		git_repository *repo,
		git_remote *remote,
		const char *reflog_message)
{
	int error = 0;
	size_t refs_len;
	git_refspec *refspec;
	const git_remote_head *remote_head, **refs;
	const git_oid *remote_head_id;
	git_buf remote_master_name = GIT_BUF_INIT;
	git_buf branch = GIT_BUF_INIT;

	if ((error = git_remote_ls(&refs, &refs_len, remote)) < 0)
		return error;

	/* We cloned an empty repository or one with an unborn HEAD */
	if (refs_len == 0 || strcmp(refs[0]->name, GIT_HEAD_FILE))
		return setup_tracking_config(
			repo, "master", GIT_REMOTE_ORIGIN, GIT_REFS_HEADS_MASTER_FILE);

	/* We know we have HEAD, let's see where it points */
	remote_head = refs[0];
	assert(remote_head);

	remote_head_id = &remote_head->oid;

	error = git_remote_default_branch(&branch, remote);
	if (error == GIT_ENOTFOUND) {
		error = git_repository_set_head_detached(
			repo, remote_head_id);
		goto cleanup;
	}

	refspec = git_remote__matching_refspec(remote, git_buf_cstr(&branch));

	if (refspec == NULL) {
		git_error_set(GIT_ERROR_NET, "the remote's default branch does not fit the refspec configuration");
		error = GIT_EINVALIDSPEC;
		goto cleanup;
	}

	/* Determine the remote tracking reference name from the local master */
	if ((error = git_refspec_transform(
		&remote_master_name,
		refspec,
		git_buf_cstr(&branch))) < 0)
		goto cleanup;

	error = update_head_to_new_branch(
		repo,
		remote_head_id,
		git_buf_cstr(&branch),
		reflog_message);

cleanup:
	git_buf_dispose(&remote_master_name);
	git_buf_dispose(&branch);

	return error;
}