void test_network_remotes__transform_r(void) { git_buf buf = GIT_BUF_INIT; cl_git_pass(git_refspec_transform_r(&buf, _refspec, "refs/heads/master")); cl_assert_equal_s(git_buf_cstr(&buf), "refs/remotes/test/master"); git_buf_free(&buf); }
int git_branch_upstream__name( git_buf *tracking_name, git_repository *repo, const char *canonical_branch_name) { 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_name && canonical_branch_name); if (!git_reference__is_branch(canonical_branch_name)) return not_a_local_branch(canonical_branch_name); if ((error = retrieve_upstream_configuration( &remote_name, repo, canonical_branch_name, "branch.%s.remote")) < 0) goto cleanup; if ((error = retrieve_upstream_configuration( &merge_name, repo, canonical_branch_name, "branch.%s.merge")) < 0) goto cleanup; if (!*remote_name || !*merge_name) { giterr_set(GITERR_REFERENCE, "branch '%s' does not have an upstream", canonical_branch_name); error = GIT_ENOTFOUND; goto cleanup; } if (strcmp(".", remote_name) != 0) { if ((error = git_remote_load(&remote, repo, remote_name)) < 0) goto cleanup; refspec = git_remote__matching_refspec(remote, merge_name); if (!refspec) { 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_buf_set(tracking_name, git_buf_cstr(&buf), git_buf_len(&buf)); cleanup: git_remote_free(remote); git_buf_free(&buf); return error; }
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; }
static int update_head_to_remote(git_repository *repo, git_remote *remote) { int retcode = -1; git_refspec dummy_spec; git_remote_head *remote_head; struct head_info head_info; git_buf remote_master_name = GIT_BUF_INIT; /* Did we just clone an empty repository? */ if (remote->refs.length == 0) { return setup_tracking_config( repo, "master", GIT_REMOTE_ORIGIN, GIT_REFS_HEADS_MASTER_FILE); } /* Get the remote's HEAD. This is always the first ref in remote->refs. */ remote_head = NULL; if (!remote->transport->ls(remote->transport, get_head_callback, &remote_head)) return -1; assert(remote_head); git_oid_cpy(&head_info.remote_head_oid, &remote_head->oid); git_buf_init(&head_info.branchname, 16); head_info.repo = repo; head_info.refspec = git_remote__matching_refspec(remote, GIT_REFS_HEADS_MASTER_FILE); head_info.found = 0; if (head_info.refspec == NULL) { memset(&dummy_spec, 0, sizeof(git_refspec)); head_info.refspec = &dummy_spec; } /* Determine the remote tracking reference name from the local master */ if (git_refspec_transform_r( &remote_master_name, head_info.refspec, GIT_REFS_HEADS_MASTER_FILE) < 0) return -1; /* Check to see if the remote HEAD points to the remote master */ if (reference_matches_remote_head(git_buf_cstr(&remote_master_name), &head_info) < 0) goto cleanup; if (head_info.found) { retcode = update_head_to_new_branch( repo, &head_info.remote_head_oid, git_buf_cstr(&head_info.branchname)); goto cleanup; } /* Not master. Check all the other refs. */ if (git_reference_foreach_name( repo, reference_matches_remote_head, &head_info) < 0) goto cleanup; if (head_info.found) { retcode = update_head_to_new_branch( repo, &head_info.remote_head_oid, git_buf_cstr(&head_info.branchname)); goto cleanup; } else { retcode = git_repository_set_head_detached( repo, &head_info.remote_head_oid); goto cleanup; } cleanup: git_buf_free(&remote_master_name); git_buf_free(&head_info.branchname); return retcode; }