upstream.c 6.4 KB
Newer Older
1
#include "clar_libgit2.h"
2
#include "config/config_helpers.h"
3 4 5
#include "refs.h"

static git_repository *repo;
6
static git_reference *branch, *upstream;
7

8
void test_refs_branches_upstream__initialize(void)
9 10 11 12
{
	cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git")));

	branch = NULL;
13
	upstream = NULL;
14 15
}

16
void test_refs_branches_upstream__cleanup(void)
17
{
18
	git_reference_free(upstream);
19
	git_reference_free(branch);
20
	branch = NULL;
21 22

	git_repository_free(repo);
23
	repo = NULL;
24 25
}

26
void test_refs_branches_upstream__can_retrieve_the_remote_tracking_reference_of_a_local_branch(void)
27 28 29
{
	cl_git_pass(git_reference_lookup(&branch, repo, "refs/heads/master"));

30
	cl_git_pass(git_branch_upstream(&upstream, branch));
31

32
	cl_assert_equal_s("refs/remotes/test/master", git_reference_name(upstream));
33 34
}

35
void test_refs_branches_upstream__can_retrieve_the_local_upstream_reference_of_a_local_branch(void)
36 37 38
{
	cl_git_pass(git_reference_lookup(&branch, repo, "refs/heads/track-local"));

39
	cl_git_pass(git_branch_upstream(&upstream, branch));
40

41
	cl_assert_equal_s("refs/heads/master", git_reference_name(upstream));
42 43
}

44
void test_refs_branches_upstream__cannot_retrieve_a_remote_upstream_reference_from_a_non_branch(void)
45 46 47
{
	cl_git_pass(git_reference_lookup(&branch, repo, "refs/tags/e90810b"));

48
	cl_git_fail(git_branch_upstream(&upstream, branch));
49 50
}

51
void test_refs_branches_upstream__trying_to_retrieve_a_remote_tracking_reference_from_a_plain_local_branch_returns_GIT_ENOTFOUND(void)
52 53 54
{
	cl_git_pass(git_reference_lookup(&branch, repo, "refs/heads/subtrees"));

55
	cl_assert_equal_i(GIT_ENOTFOUND, git_branch_upstream(&upstream, branch));
56
}
57

58
void test_refs_branches_upstream__trying_to_retrieve_a_remote_tracking_reference_from_a_branch_with_no_fetchspec_returns_GIT_ENOTFOUND(void)
59 60 61
{
	cl_git_pass(git_reference_lookup(&branch, repo, "refs/heads/cannot-fetch"));

62
	cl_assert_equal_i(GIT_ENOTFOUND, git_branch_upstream(&upstream, branch));
63
}
64

65 66 67 68 69 70 71 72 73
void test_refs_branches_upstream__upstream_remote(void)
{
	git_buf buf = GIT_BUF_INIT;

	cl_git_pass(git_branch_upstream_remote(&buf, repo, "refs/heads/master"));
	cl_assert_equal_s("test", buf.ptr);
	git_buf_free(&buf);
}

74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
void test_refs_branches_upstream__upstream_remote_empty_value(void)
{
	git_repository *repository;
	git_config *cfg;
	git_buf buf = GIT_BUF_INIT;

	repository = cl_git_sandbox_init("testrepo.git");
	cl_git_pass(git_repository_config(&cfg, repository));
	cl_git_pass(git_config_set_string(cfg, "branch.master.remote", ""));
	cl_git_fail_with(GIT_ENOTFOUND, git_branch_upstream_remote(&buf, repository, "refs/heads/master"));

	cl_git_pass(git_config_delete_entry(cfg, "branch.master.remote"));
	cl_git_fail_with(GIT_ENOTFOUND, git_branch_upstream_remote(&buf, repository, "refs/heads/master"));
	cl_git_sandbox_cleanup();
}

nulltoken committed
90
static void assert_merge_and_or_remote_key_missing(git_repository *repository, const git_commit *target, const char *entry_name)
91 92 93
{
	git_reference *branch;

Ben Straub committed
94
	cl_assert_equal_i(GIT_OBJ_COMMIT, git_object_type((git_object*)target));
95
	cl_git_pass(git_branch_create(&branch, repository, entry_name, (git_commit*)target, 0));
96

97
	cl_assert_equal_i(GIT_ENOTFOUND, git_branch_upstream(&upstream, branch));
98 99 100 101

	git_reference_free(branch);
}

102
void test_refs_branches_upstream__retrieve_a_remote_tracking_reference_from_a_branch_with_no_remote_returns_GIT_ENOTFOUND(void)
103 104 105
{
	git_reference *head;
	git_repository *repository;
nulltoken committed
106
	git_commit *target;
107 108 109 110

	repository = cl_git_sandbox_init("testrepo.git");

	cl_git_pass(git_repository_head(&head, repository));
nulltoken committed
111
	cl_git_pass(git_reference_peel(((git_object **)&target), head, GIT_OBJ_COMMIT));
112 113 114 115 116 117
	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");

nulltoken committed
118
	git_commit_free(target);
119 120 121

	cl_git_sandbox_cleanup();
}
122 123 124 125 126 127 128 129

void test_refs_branches_upstream__set_unset_upstream(void)
{
	git_reference *branch;
	git_repository *repository;

	repository = cl_git_sandbox_init("testrepo.git");

130
	/* remote */
131 132 133
	cl_git_pass(git_reference_lookup(&branch, repository, "refs/heads/test"));
	cl_git_pass(git_branch_set_upstream(branch, "test/master"));

134 135
	assert_config_entry_value(repository, "branch.test.remote", "test");
	assert_config_entry_value(repository, "branch.test.merge", "refs/heads/master");
136

nulltoken committed
137 138
	git_reference_free(branch);

139 140 141 142
	/* local */
	cl_git_pass(git_reference_lookup(&branch, repository, "refs/heads/test"));
	cl_git_pass(git_branch_set_upstream(branch, "master"));

143 144
	assert_config_entry_value(repository, "branch.test.remote", ".");
	assert_config_entry_value(repository, "branch.test.merge", "refs/heads/master");
145 146

	/* unset */
147
	cl_git_pass(git_branch_set_upstream(branch, NULL));
148 149
	assert_config_entry_existence(repository, "branch.test.remote", false);
	assert_config_entry_existence(repository, "branch.test.merge", false);
150 151 152 153 154

	git_reference_free(branch);

	cl_git_pass(git_reference_lookup(&branch, repository, "refs/heads/master"));
	cl_git_pass(git_branch_set_upstream(branch, NULL));
155 156
	assert_config_entry_existence(repository, "branch.test.remote", false);
	assert_config_entry_existence(repository, "branch.test.merge", false);
157 158 159 160 161

	git_reference_free(branch);

	cl_git_sandbox_cleanup();
}
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193

void test_refs_branches_upstream__no_fetch_refspec(void)
{
	git_reference *ref, *branch;
	git_repository *repo;
	git_remote *remote;
	git_config *cfg;

	repo = cl_git_sandbox_init("testrepo.git");

	cl_git_pass(git_remote_create_with_fetchspec(&remote, repo, "matching", ".", NULL));
	cl_git_pass(git_remote_add_push(repo, "matching", ":"));

	cl_git_pass(git_reference_lookup(&branch, repo, "refs/heads/test"));
	cl_git_pass(git_reference_create(&ref, repo, "refs/remotes/matching/master", git_reference_target(branch), 1, "fetch"));
	cl_git_fail(git_branch_set_upstream(branch, "matching/master"));
	cl_assert_equal_s("Could not determine remote for 'refs/remotes/matching/master'",
			  giterr_last()->message);

	/* we can't set it automatically, so let's test the user setting it by hand */
	cl_git_pass(git_repository_config(&cfg, repo));
	cl_git_pass(git_config_set_string(cfg, "branch.test.remote", "matching"));
	cl_git_pass(git_config_set_string(cfg, "branch.test.merge", "refs/heads/master"));
	/* we still can't find it because there is no rule for that reference */
	cl_git_fail_with(GIT_ENOTFOUND, git_branch_upstream(&ref, branch));

	git_reference_free(ref);
	git_reference_free(branch);
	git_remote_free(remote);

	cl_git_sandbox_cleanup();
}