mirror of
https://git.proxmox.com/git/libgit2
synced 2026-01-03 19:59:33 +00:00
Merge pull request #1450 from carlosmn/branch-upstream
Branch upstream configuration
This commit is contained in:
commit
ea8bac37b0
@ -171,10 +171,22 @@ GIT_EXTERN(int) git_branch_name(const char **out,
|
||||
* @return 0 on success; GIT_ENOTFOUND when no remote tracking
|
||||
* reference exists, otherwise an error code.
|
||||
*/
|
||||
GIT_EXTERN(int) git_branch_tracking(
|
||||
GIT_EXTERN(int) git_branch_upstream(
|
||||
git_reference **out,
|
||||
git_reference *branch);
|
||||
|
||||
/**
|
||||
* Set the upstream configuration for a given local branch
|
||||
*
|
||||
* @param branch the branch to configure
|
||||
*
|
||||
* @param upstream_name remote-tracking or local branch to set as
|
||||
* upstream. Pass NULL to unset.
|
||||
*
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_branch_set_upstream(git_reference *branch, const char *upstream_name);
|
||||
|
||||
/**
|
||||
* Return the name of the reference supporting the remote tracking branch,
|
||||
* given the name of a local branch reference.
|
||||
@ -193,7 +205,7 @@ GIT_EXTERN(int) git_branch_tracking(
|
||||
* including the trailing NUL byte; GIT_ENOTFOUND when no remote tracking
|
||||
* reference exists, otherwise an error code.
|
||||
*/
|
||||
GIT_EXTERN(int) git_branch_tracking_name(
|
||||
GIT_EXTERN(int) git_branch_upstream_name(
|
||||
char *tracking_branch_name_out,
|
||||
size_t buffer_size,
|
||||
git_repository *repo,
|
||||
|
||||
179
src/branch.c
179
src/branch.c
@ -228,7 +228,7 @@ int git_branch_name(const char **out, git_reference *ref)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int retrieve_tracking_configuration(
|
||||
static int retrieve_upstream_configuration(
|
||||
const char **out,
|
||||
git_repository *repo,
|
||||
const char *canonical_branch_name,
|
||||
@ -250,7 +250,7 @@ static int retrieve_tracking_configuration(
|
||||
return error;
|
||||
}
|
||||
|
||||
int git_branch_tracking__name(
|
||||
int git_branch_upstream__name(
|
||||
git_buf *tracking_name,
|
||||
git_repository *repo,
|
||||
const char *canonical_branch_name)
|
||||
@ -266,11 +266,11 @@ int git_branch_tracking__name(
|
||||
if (!git_reference__is_branch(canonical_branch_name))
|
||||
return not_a_local_branch(canonical_branch_name);
|
||||
|
||||
if ((error = retrieve_tracking_configuration(
|
||||
if ((error = retrieve_upstream_configuration(
|
||||
&remote_name, repo, canonical_branch_name, "branch.%s.remote")) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if ((error = retrieve_tracking_configuration(
|
||||
if ((error = retrieve_upstream_configuration(
|
||||
&merge_name, repo, canonical_branch_name, "branch.%s.merge")) < 0)
|
||||
goto cleanup;
|
||||
|
||||
@ -305,23 +305,16 @@ cleanup:
|
||||
return error;
|
||||
}
|
||||
|
||||
int git_branch_remote_name(
|
||||
char *remote_name_out,
|
||||
size_t buffer_size,
|
||||
git_repository *repo,
|
||||
const char *canonical_branch_name)
|
||||
static int remote_name(git_buf *buf, git_repository *repo, const char *canonical_branch_name)
|
||||
{
|
||||
git_strarray remote_list = {0};
|
||||
size_t i, remote_name_size;
|
||||
size_t i;
|
||||
git_remote *remote;
|
||||
const git_refspec *fetchspec;
|
||||
int error = 0;
|
||||
char *remote_name = NULL;
|
||||
|
||||
assert(repo && canonical_branch_name);
|
||||
|
||||
if (remote_name_out && buffer_size)
|
||||
*remote_name_out = '\0';
|
||||
assert(buf && repo && canonical_branch_name);
|
||||
|
||||
/* Verify that this is a remote branch */
|
||||
if (!git_reference__is_remote(canonical_branch_name)) {
|
||||
@ -338,7 +331,7 @@ int git_branch_remote_name(
|
||||
/* Find matching remotes */
|
||||
for (i = 0; i < remote_list.count; i++) {
|
||||
if ((error = git_remote_load(&remote, repo, remote_list.strings[i])) < 0)
|
||||
goto cleanup;
|
||||
continue;
|
||||
|
||||
fetchspec = git_remote_fetchspec(remote);
|
||||
|
||||
@ -362,23 +355,10 @@ int git_branch_remote_name(
|
||||
}
|
||||
|
||||
if (remote_name) {
|
||||
remote_name_size = strlen(remote_name) + 1;
|
||||
error = (int) remote_name_size;
|
||||
|
||||
if (remote_name_out) {
|
||||
if(remote_name_size > buffer_size) {
|
||||
giterr_set(
|
||||
GITERR_INVALID,
|
||||
"Buffer too short to hold the remote name.");
|
||||
error = GIT_ERROR;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
memcpy(remote_name_out, remote_name, remote_name_size);
|
||||
}
|
||||
git_buf_clear(buf);
|
||||
error = git_buf_puts(buf, remote_name);
|
||||
} else {
|
||||
error = GIT_ENOTFOUND;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
@ -386,7 +366,24 @@ cleanup:
|
||||
return error;
|
||||
}
|
||||
|
||||
int git_branch_tracking_name(
|
||||
int git_branch_remote_name(char *buffer, size_t buffer_len, git_repository *repo, const char *refname)
|
||||
{
|
||||
int ret;
|
||||
git_buf buf = GIT_BUF_INIT;
|
||||
|
||||
if ((ret = remote_name(&buf, repo, refname)) < 0)
|
||||
return ret;
|
||||
|
||||
if (buffer)
|
||||
git_buf_copy_cstr(buffer, buffer_len, &buf);
|
||||
|
||||
ret = git_buf_len(&buf) + 1;
|
||||
git_buf_free(&buf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int git_branch_upstream_name(
|
||||
char *tracking_branch_name_out,
|
||||
size_t buffer_size,
|
||||
git_repository *repo,
|
||||
@ -400,7 +397,7 @@ int git_branch_tracking_name(
|
||||
if (tracking_branch_name_out && buffer_size)
|
||||
*tracking_branch_name_out = '\0';
|
||||
|
||||
if ((error = git_branch_tracking__name(
|
||||
if ((error = git_branch_upstream__name(
|
||||
&buf, repo, canonical_branch_name)) < 0)
|
||||
goto cleanup;
|
||||
|
||||
@ -422,14 +419,14 @@ cleanup:
|
||||
return (int)error;
|
||||
}
|
||||
|
||||
int git_branch_tracking(
|
||||
int git_branch_upstream(
|
||||
git_reference **tracking_out,
|
||||
git_reference *branch)
|
||||
{
|
||||
int error;
|
||||
git_buf tracking_name = GIT_BUF_INIT;
|
||||
|
||||
if ((error = git_branch_tracking__name(&tracking_name,
|
||||
if ((error = git_branch_upstream__name(&tracking_name,
|
||||
git_reference_owner(branch), git_reference_name(branch))) < 0)
|
||||
return error;
|
||||
|
||||
@ -442,6 +439,120 @@ int git_branch_tracking(
|
||||
return error;
|
||||
}
|
||||
|
||||
static int unset_upstream(git_config *config, const char *shortname)
|
||||
{
|
||||
git_buf buf = GIT_BUF_INIT;
|
||||
|
||||
if (git_buf_printf(&buf, "branch.%s.remote", shortname) < 0)
|
||||
return -1;
|
||||
|
||||
if (git_config_delete_entry(config, git_buf_cstr(&buf)) < 0)
|
||||
goto on_error;
|
||||
|
||||
git_buf_clear(&buf);
|
||||
if (git_buf_printf(&buf, "branch.%s.merge", shortname) < 0)
|
||||
goto on_error;
|
||||
|
||||
if (git_config_delete_entry(config, git_buf_cstr(&buf)) < 0)
|
||||
goto on_error;
|
||||
|
||||
git_buf_free(&buf);
|
||||
return 0;
|
||||
|
||||
on_error:
|
||||
git_buf_free(&buf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
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;
|
||||
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
|
||||
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)
|
||||
git_buf_puts(&value, ".");
|
||||
else
|
||||
remote_name(&value, repo, git_reference_name(upstream));
|
||||
|
||||
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) {
|
||||
if (git_buf_puts(&value, git_reference_name(branch)) < 0)
|
||||
goto on_error;
|
||||
} else {
|
||||
/* Get the remoe-tracking branch's refname in its repo */
|
||||
if (git_remote_load(&remote, repo, git_buf_cstr(&value)) < 0)
|
||||
goto on_error;
|
||||
|
||||
fetchspec = git_remote_fetchspec(remote);
|
||||
git_buf_clear(&value);
|
||||
if (git_refspec_transform_l(&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;
|
||||
}
|
||||
|
||||
int git_branch_is_head(
|
||||
git_reference *branch)
|
||||
{
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
|
||||
#include "buffer.h"
|
||||
|
||||
int git_branch_tracking__name(
|
||||
int git_branch_upstream__name(
|
||||
git_buf *tracking_name,
|
||||
git_repository *repo,
|
||||
const char *canonical_branch_name);
|
||||
|
||||
@ -705,7 +705,7 @@ static int remote_head_for_ref(git_remote_head **out, git_remote *remote, git_ve
|
||||
|
||||
if ((error = git_reference_resolve(&resolved_ref, ref)) < 0 ||
|
||||
(!git_reference_is_branch(resolved_ref)) ||
|
||||
(error = git_branch_tracking(&tracking_ref, resolved_ref)) < 0 ||
|
||||
(error = git_branch_upstream(&tracking_ref, resolved_ref)) < 0 ||
|
||||
(error = git_refspec_transform_l(&remote_name, &remote->fetch, git_reference_name(tracking_ref))) < 0) {
|
||||
/* Not an error if HEAD is orphaned or no tracking branch */
|
||||
if (error == GIT_ENOTFOUND)
|
||||
|
||||
@ -356,7 +356,7 @@ static int retrieve_remote_tracking_reference(git_reference **base_ref, const ch
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if ((error = git_branch_tracking(&tracking, ref)) < 0)
|
||||
if ((error = git_branch_upstream(&tracking, ref)) < 0)
|
||||
goto cleanup;
|
||||
|
||||
*base_ref = tracking;
|
||||
|
||||
@ -1327,7 +1327,7 @@ static int lookup_head_remote(git_buf *url, git_repository *repo)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if ((error = git_branch_tracking(&remote, head)) < 0)
|
||||
if ((error = git_branch_upstream(&remote, head)) < 0)
|
||||
goto cleanup;
|
||||
|
||||
/* remote should refer to something like refs/remotes/ORIGIN/BRANCH */
|
||||
|
||||
@ -49,7 +49,7 @@ void test_clone_empty__can_clone_an_empty_local_repo_barely(void)
|
||||
|
||||
/* ...one can still retrieve the name of the remote tracking reference */
|
||||
cl_assert_equal_i((int)strlen(expected_tracked_branch_name) + 1,
|
||||
git_branch_tracking_name(buffer, 1024, g_repo_cloned, local_name));
|
||||
git_branch_upstream_name(buffer, 1024, g_repo_cloned, local_name));
|
||||
|
||||
cl_assert_equal_s(expected_tracked_branch_name, buffer);
|
||||
|
||||
|
||||
@ -42,7 +42,7 @@ void test_refs_branches_remote__insufficient_buffer_returns_error(void)
|
||||
|
||||
cl_git_fail_with(git_branch_remote_name(remotename,
|
||||
expected_remote_name_length - 1, g_repo, remote_tracking_branch_name),
|
||||
GIT_ERROR);
|
||||
expected_remote_name_length);
|
||||
}
|
||||
|
||||
void test_refs_branches_remote__no_matching_remote_returns_error(void)
|
||||
|
||||
@ -1,95 +0,0 @@
|
||||
#include "clar_libgit2.h"
|
||||
#include "refs.h"
|
||||
|
||||
static git_repository *repo;
|
||||
static git_reference *branch, *tracking;
|
||||
|
||||
void test_refs_branches_tracking__initialize(void)
|
||||
{
|
||||
cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git")));
|
||||
|
||||
branch = NULL;
|
||||
tracking = NULL;
|
||||
}
|
||||
|
||||
void test_refs_branches_tracking__cleanup(void)
|
||||
{
|
||||
git_reference_free(tracking);
|
||||
git_reference_free(branch);
|
||||
branch = NULL;
|
||||
|
||||
git_repository_free(repo);
|
||||
repo = NULL;
|
||||
}
|
||||
|
||||
void test_refs_branches_tracking__can_retrieve_the_remote_tracking_reference_of_a_local_branch(void)
|
||||
{
|
||||
cl_git_pass(git_reference_lookup(&branch, repo, "refs/heads/master"));
|
||||
|
||||
cl_git_pass(git_branch_tracking(&tracking, branch));
|
||||
|
||||
cl_assert_equal_s("refs/remotes/test/master", git_reference_name(tracking));
|
||||
}
|
||||
|
||||
void test_refs_branches_tracking__can_retrieve_the_local_tracking_reference_of_a_local_branch(void)
|
||||
{
|
||||
cl_git_pass(git_reference_lookup(&branch, repo, "refs/heads/track-local"));
|
||||
|
||||
cl_git_pass(git_branch_tracking(&tracking, branch));
|
||||
|
||||
cl_assert_equal_s("refs/heads/master", git_reference_name(tracking));
|
||||
}
|
||||
|
||||
void test_refs_branches_tracking__cannot_retrieve_a_remote_tracking_reference_from_a_non_branch(void)
|
||||
{
|
||||
cl_git_pass(git_reference_lookup(&branch, repo, "refs/tags/e90810b"));
|
||||
|
||||
cl_git_fail(git_branch_tracking(&tracking, branch));
|
||||
}
|
||||
|
||||
void test_refs_branches_tracking__trying_to_retrieve_a_remote_tracking_reference_from_a_plain_local_branch_returns_GIT_ENOTFOUND(void)
|
||||
{
|
||||
cl_git_pass(git_reference_lookup(&branch, repo, "refs/heads/subtrees"));
|
||||
|
||||
cl_assert_equal_i(GIT_ENOTFOUND, git_branch_tracking(&tracking, branch));
|
||||
}
|
||||
|
||||
void test_refs_branches_tracking__trying_to_retrieve_a_remote_tracking_reference_from_a_branch_with_no_fetchspec_returns_GIT_ENOTFOUND(void)
|
||||
{
|
||||
cl_git_pass(git_reference_lookup(&branch, repo, "refs/heads/cannot-fetch"));
|
||||
|
||||
cl_assert_equal_i(GIT_ENOTFOUND, git_branch_tracking(&tracking, branch));
|
||||
}
|
||||
|
||||
static void assert_merge_and_or_remote_key_missing(git_repository *repository, const git_commit *target, const char *entry_name)
|
||||
{
|
||||
git_reference *branch;
|
||||
|
||||
cl_assert_equal_i(GIT_OBJ_COMMIT, git_object_type((git_object*)target));
|
||||
cl_git_pass(git_branch_create(&branch, repository, entry_name, (git_commit*)target, 0));
|
||||
|
||||
cl_assert_equal_i(GIT_ENOTFOUND, git_branch_tracking(&tracking, branch));
|
||||
|
||||
git_reference_free(branch);
|
||||
}
|
||||
|
||||
void test_refs_branches_tracking__retrieve_a_remote_tracking_reference_from_a_branch_with_no_remote_returns_GIT_ENOTFOUND(void)
|
||||
{
|
||||
git_reference *head;
|
||||
git_repository *repository;
|
||||
git_commit *target;
|
||||
|
||||
repository = cl_git_sandbox_init("testrepo.git");
|
||||
|
||||
cl_git_pass(git_repository_head(&head, repository));
|
||||
cl_git_pass(git_reference_peel(((git_object **)&target), head, GIT_OBJ_COMMIT));
|
||||
git_reference_free(head);
|
||||
|
||||
assert_merge_and_or_remote_key_missing(repository, target, "remoteless");
|
||||
assert_merge_and_or_remote_key_missing(repository, target, "mergeless");
|
||||
assert_merge_and_or_remote_key_missing(repository, target, "mergeandremoteless");
|
||||
|
||||
git_commit_free(target);
|
||||
|
||||
cl_git_sandbox_cleanup();
|
||||
}
|
||||
@ -1,42 +0,0 @@
|
||||
#include "clar_libgit2.h"
|
||||
#include "branch.h"
|
||||
|
||||
static git_repository *repo;
|
||||
static git_buf tracking_name;
|
||||
|
||||
void test_refs_branches_trackingname__initialize(void)
|
||||
{
|
||||
cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git")));
|
||||
|
||||
git_buf_init(&tracking_name, 0);
|
||||
}
|
||||
|
||||
void test_refs_branches_trackingname__cleanup(void)
|
||||
{
|
||||
git_buf_free(&tracking_name);
|
||||
|
||||
git_repository_free(repo);
|
||||
repo = NULL;
|
||||
}
|
||||
|
||||
void test_refs_branches_trackingname__can_retrieve_the_remote_tracking_reference_name_of_a_local_branch(void)
|
||||
{
|
||||
cl_git_pass(git_branch_tracking__name(
|
||||
&tracking_name, repo, "refs/heads/master"));
|
||||
|
||||
cl_assert_equal_s("refs/remotes/test/master", git_buf_cstr(&tracking_name));
|
||||
}
|
||||
|
||||
void test_refs_branches_trackingname__can_retrieve_the_local_tracking_reference_name_of_a_local_branch(void)
|
||||
{
|
||||
cl_git_pass(git_branch_tracking__name(
|
||||
&tracking_name, repo, "refs/heads/track-local"));
|
||||
|
||||
cl_assert_equal_s("refs/heads/master", git_buf_cstr(&tracking_name));
|
||||
}
|
||||
|
||||
void test_refs_branches_trackingname__can_return_the_size_of_thelocal_tracking_reference_name_of_a_local_branch(void)
|
||||
{
|
||||
cl_assert_equal_i((int)strlen("refs/heads/master") + 1,
|
||||
git_branch_tracking_name(NULL, 0, repo, "refs/heads/track-local"));
|
||||
}
|
||||
130
tests-clar/refs/branches/upstream.c
Normal file
130
tests-clar/refs/branches/upstream.c
Normal file
@ -0,0 +1,130 @@
|
||||
#include "clar_libgit2.h"
|
||||
#include "refs.h"
|
||||
|
||||
static git_repository *repo;
|
||||
static git_reference *branch, *upstream;
|
||||
|
||||
void test_refs_branches_upstream__initialize(void)
|
||||
{
|
||||
cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git")));
|
||||
|
||||
branch = NULL;
|
||||
upstream = NULL;
|
||||
}
|
||||
|
||||
void test_refs_branches_upstream__cleanup(void)
|
||||
{
|
||||
git_reference_free(upstream);
|
||||
git_reference_free(branch);
|
||||
branch = NULL;
|
||||
|
||||
git_repository_free(repo);
|
||||
repo = NULL;
|
||||
}
|
||||
|
||||
void test_refs_branches_upstream__can_retrieve_the_remote_tracking_reference_of_a_local_branch(void)
|
||||
{
|
||||
cl_git_pass(git_reference_lookup(&branch, repo, "refs/heads/master"));
|
||||
|
||||
cl_git_pass(git_branch_upstream(&upstream, branch));
|
||||
|
||||
cl_assert_equal_s("refs/remotes/test/master", git_reference_name(upstream));
|
||||
}
|
||||
|
||||
void test_refs_branches_upstream__can_retrieve_the_local_upstream_reference_of_a_local_branch(void)
|
||||
{
|
||||
cl_git_pass(git_reference_lookup(&branch, repo, "refs/heads/track-local"));
|
||||
|
||||
cl_git_pass(git_branch_upstream(&upstream, branch));
|
||||
|
||||
cl_assert_equal_s("refs/heads/master", git_reference_name(upstream));
|
||||
}
|
||||
|
||||
void test_refs_branches_upstream__cannot_retrieve_a_remote_upstream_reference_from_a_non_branch(void)
|
||||
{
|
||||
cl_git_pass(git_reference_lookup(&branch, repo, "refs/tags/e90810b"));
|
||||
|
||||
cl_git_fail(git_branch_upstream(&upstream, branch));
|
||||
}
|
||||
|
||||
void test_refs_branches_upstream__trying_to_retrieve_a_remote_tracking_reference_from_a_plain_local_branch_returns_GIT_ENOTFOUND(void)
|
||||
{
|
||||
cl_git_pass(git_reference_lookup(&branch, repo, "refs/heads/subtrees"));
|
||||
|
||||
cl_assert_equal_i(GIT_ENOTFOUND, git_branch_upstream(&upstream, branch));
|
||||
}
|
||||
|
||||
void test_refs_branches_upstream__trying_to_retrieve_a_remote_tracking_reference_from_a_branch_with_no_fetchspec_returns_GIT_ENOTFOUND(void)
|
||||
{
|
||||
cl_git_pass(git_reference_lookup(&branch, repo, "refs/heads/cannot-fetch"));
|
||||
|
||||
cl_assert_equal_i(GIT_ENOTFOUND, git_branch_upstream(&upstream, branch));
|
||||
}
|
||||
|
||||
static void assert_merge_and_or_remote_key_missing(git_repository *repository, const git_commit *target, const char *entry_name)
|
||||
{
|
||||
git_reference *branch;
|
||||
|
||||
cl_assert_equal_i(GIT_OBJ_COMMIT, git_object_type((git_object*)target));
|
||||
cl_git_pass(git_branch_create(&branch, repository, entry_name, (git_commit*)target, 0));
|
||||
|
||||
cl_assert_equal_i(GIT_ENOTFOUND, git_branch_upstream(&upstream, branch));
|
||||
|
||||
git_reference_free(branch);
|
||||
}
|
||||
|
||||
void test_refs_branches_upstream__retrieve_a_remote_tracking_reference_from_a_branch_with_no_remote_returns_GIT_ENOTFOUND(void)
|
||||
{
|
||||
git_reference *head;
|
||||
git_repository *repository;
|
||||
git_commit *target;
|
||||
|
||||
repository = cl_git_sandbox_init("testrepo.git");
|
||||
|
||||
cl_git_pass(git_repository_head(&head, repository));
|
||||
cl_git_pass(git_reference_peel(((git_object **)&target), head, GIT_OBJ_COMMIT));
|
||||
git_reference_free(head);
|
||||
|
||||
assert_merge_and_or_remote_key_missing(repository, target, "remoteless");
|
||||
assert_merge_and_or_remote_key_missing(repository, target, "mergeless");
|
||||
assert_merge_and_or_remote_key_missing(repository, target, "mergeandremoteless");
|
||||
|
||||
git_commit_free(target);
|
||||
|
||||
cl_git_sandbox_cleanup();
|
||||
}
|
||||
|
||||
void test_refs_branches_upstream__set_unset_upstream(void)
|
||||
{
|
||||
git_reference *branch;
|
||||
git_repository *repository;
|
||||
const char *value;
|
||||
git_config *config;
|
||||
|
||||
repository = cl_git_sandbox_init("testrepo.git");
|
||||
|
||||
cl_git_pass(git_reference_lookup(&branch, repository, "refs/heads/test"));
|
||||
cl_git_pass(git_branch_set_upstream(branch, "test/master"));
|
||||
|
||||
cl_git_pass(git_repository_config(&config, repository));
|
||||
cl_git_pass(git_config_get_string(&value, config, "branch.test.remote"));
|
||||
cl_assert_equal_s(value, "test");
|
||||
cl_git_pass(git_config_get_string(&value, config, "branch.test.merge"));
|
||||
cl_assert_equal_s(value, "refs/heads/master");
|
||||
|
||||
cl_git_pass(git_branch_set_upstream(branch, NULL));
|
||||
cl_git_fail_with(git_config_get_string(&value, config, "branch.test.merge"), GIT_ENOTFOUND);
|
||||
cl_git_fail_with(git_config_get_string(&value, config, "branch.test.remote"), GIT_ENOTFOUND);
|
||||
|
||||
git_reference_free(branch);
|
||||
|
||||
cl_git_pass(git_reference_lookup(&branch, repository, "refs/heads/master"));
|
||||
cl_git_pass(git_branch_set_upstream(branch, NULL));
|
||||
cl_git_fail_with(git_config_get_string(&value, config, "branch.master.merge"), GIT_ENOTFOUND);
|
||||
cl_git_fail_with(git_config_get_string(&value, config, "branch.master.remote"), GIT_ENOTFOUND);
|
||||
|
||||
git_reference_free(branch);
|
||||
|
||||
git_config_free(config);
|
||||
cl_git_sandbox_cleanup();
|
||||
}
|
||||
42
tests-clar/refs/branches/upstreamname.c
Normal file
42
tests-clar/refs/branches/upstreamname.c
Normal file
@ -0,0 +1,42 @@
|
||||
#include "clar_libgit2.h"
|
||||
#include "branch.h"
|
||||
|
||||
static git_repository *repo;
|
||||
static git_buf upstream_name;
|
||||
|
||||
void test_refs_branches_upstreamname__initialize(void)
|
||||
{
|
||||
cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git")));
|
||||
|
||||
git_buf_init(&upstream_name, 0);
|
||||
}
|
||||
|
||||
void test_refs_branches_upstreamname__cleanup(void)
|
||||
{
|
||||
git_buf_free(&upstream_name);
|
||||
|
||||
git_repository_free(repo);
|
||||
repo = NULL;
|
||||
}
|
||||
|
||||
void test_refs_branches_upstreamname__can_retrieve_the_remote_tracking_reference_name_of_a_local_branch(void)
|
||||
{
|
||||
cl_git_pass(git_branch_upstream__name(
|
||||
&upstream_name, repo, "refs/heads/master"));
|
||||
|
||||
cl_assert_equal_s("refs/remotes/test/master", git_buf_cstr(&upstream_name));
|
||||
}
|
||||
|
||||
void test_refs_branches_upstreamname__can_retrieve_the_local_upstream_reference_name_of_a_local_branch(void)
|
||||
{
|
||||
cl_git_pass(git_branch_upstream__name(
|
||||
&upstream_name, repo, "refs/heads/track-local"));
|
||||
|
||||
cl_assert_equal_s("refs/heads/master", git_buf_cstr(&upstream_name));
|
||||
}
|
||||
|
||||
void test_refs_branches_upstreamname__can_return_the_size_of_thelocal_upstream_reference_name_of_a_local_branch(void)
|
||||
{
|
||||
cl_assert_equal_i((int)strlen("refs/heads/master") + 1,
|
||||
git_branch_upstream_name(NULL, 0, repo, "refs/heads/track-local"));
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user