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); }
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); }
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); }
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; }
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; }