PyObject * Refspec_rtransform(Refspec *self, PyObject *py_str) { char *str, *trans; int err, len, alen; PyObject *py_trans; str = py_str_to_c_str(py_str, NULL); alen = len = strlen(str); do { alen *= alen; trans = malloc(alen); if (!trans) { free(str); return PyErr_NoMemory(); } err = git_refspec_rtransform(trans, alen, self->refspec, str); } while(err == GIT_EBUFS); free(str); if (err < 0) { free(trans); Error_set(err); return NULL; } py_trans = to_unicode(trans, NULL, NULL); free(trans); return py_trans; }
void test_network_remote_remotes__transform_destination_to_source(void) { git_buf ref = GIT_BUF_INIT; cl_git_pass(git_refspec_rtransform(&ref, _refspec, "refs/remotes/test/master")); cl_assert_equal_s(ref.ptr, "refs/heads/master"); git_buf_free(&ref); }
int git_branch_set_upstream(git_reference *branch, const char *upstream_name) { git_buf key = GIT_BUF_INIT, value = GIT_BUF_INIT; git_reference *upstream; git_repository *repo; git_remote *remote = NULL; git_config *config; const char *name, *shortname; int local, error; const git_refspec *fetchspec; name = git_reference_name(branch); if (!git_reference__is_branch(name)) return not_a_local_branch(name); if (git_repository_config__weakptr(&config, git_reference_owner(branch)) < 0) return -1; shortname = name + strlen(GIT_REFS_HEADS_DIR); if (upstream_name == NULL) return unset_upstream(config, shortname); repo = git_reference_owner(branch); /* First we need to figure out whether it's a branch or remote-tracking */ if (git_branch_lookup(&upstream, repo, upstream_name, GIT_BRANCH_LOCAL) == 0) local = 1; else if (git_branch_lookup(&upstream, repo, upstream_name, GIT_BRANCH_REMOTE) == 0) local = 0; else { giterr_set(GITERR_REFERENCE, "Cannot set upstream for branch '%s'", shortname); return GIT_ENOTFOUND; } /* * If it's local, the remote is "." and the branch name is * simply the refname. Otherwise we need to figure out what * the remote-tracking branch's name on the remote is and use * that. */ if (local) error = git_buf_puts(&value, "."); else error = git_branch_remote_name(&value, repo, git_reference_name(upstream)); if (error < 0) goto on_error; if (git_buf_printf(&key, "branch.%s.remote", shortname) < 0) goto on_error; if (git_config_set_string(config, git_buf_cstr(&key), git_buf_cstr(&value)) < 0) goto on_error; if (local) { git_buf_clear(&value); if (git_buf_puts(&value, git_reference_name(upstream)) < 0) goto on_error; } else { /* Get the remoe-tracking branch's refname in its repo */ if (git_remote_lookup(&remote, repo, git_buf_cstr(&value)) < 0) goto on_error; fetchspec = git_remote__matching_dst_refspec(remote, git_reference_name(upstream)); git_buf_clear(&value); if (!fetchspec || git_refspec_rtransform(&value, fetchspec, git_reference_name(upstream)) < 0) goto on_error; git_remote_free(remote); remote = NULL; } git_buf_clear(&key); if (git_buf_printf(&key, "branch.%s.merge", shortname) < 0) goto on_error; if (git_config_set_string(config, git_buf_cstr(&key), git_buf_cstr(&value)) < 0) goto on_error; git_reference_free(upstream); git_buf_free(&key); git_buf_free(&value); return 0; on_error: git_reference_free(upstream); git_buf_free(&key); git_buf_free(&value); git_remote_free(remote); return -1; }