add.c 7.09 KB
Newer Older
1 2 3 4
#include "clar_libgit2.h"
#include "posix.h"
#include "path.h"
#include "submodule_helpers.h"
5
#include "config/config_helpers.h"
6
#include "futils.h"
7
#include "repository.h"
8
#include "git2/sys/commit.h"
9 10

static git_repository *g_repo = NULL;
11
static const char *valid_blob_id = "fa49b077972391ad58037050f2a75f74e3671e92";
12 13 14 15 16 17

void test_submodule_add__cleanup(void)
{
	cl_git_sandbox_cleanup();
}

Russell Belfer committed
18 19 20 21 22 23
static void assert_submodule_url(const char* name, const char *url)
{
	git_buf key = GIT_BUF_INIT;


	cl_git_pass(git_buf_printf(&key, "submodule.%s.url", name));
24
	assert_config_entry_value(g_repo, git_buf_cstr(&key), url);
Russell Belfer committed
25

26
	git_buf_dispose(&key);
Russell Belfer committed
27 28
}

29 30 31
void test_submodule_add__url_absolute(void)
{
	git_submodule *sm;
32 33
	git_repository *repo;
	git_buf dot_git_content = GIT_BUF_INIT;
34

Russell Belfer committed
35 36
	g_repo = setup_fixture_submod2();

37
	/* re-add existing submodule */
Russell Belfer committed
38
	cl_git_fail_with(
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
		GIT_EEXISTS,
		git_submodule_add_setup(NULL, g_repo, "whatever", "sm_unchanged", 1));

	/* add a submodule using a gitlink */

	cl_git_pass(
		git_submodule_add_setup(&sm, g_repo, "https://github.com/libgit2/libgit2.git", "sm_libgit2", 1)
		);
	git_submodule_free(sm);

	cl_assert(git_path_isfile("submod2/" "sm_libgit2" "/.git"));

	cl_assert(git_path_isdir("submod2/.git/modules"));
	cl_assert(git_path_isdir("submod2/.git/modules/" "sm_libgit2"));
	cl_assert(git_path_isfile("submod2/.git/modules/" "sm_libgit2" "/HEAD"));
	assert_submodule_url("sm_libgit2", "https://github.com/libgit2/libgit2.git");

56 57 58
	cl_git_pass(git_repository_open(&repo, "submod2/" "sm_libgit2"));

	/* Verify worktree path is relative */
59
	assert_config_entry_value(repo, "core.worktree", "../../../sm_libgit2/");
60 61 62 63 64 65

	/* Verify gitdir path is relative */
	cl_git_pass(git_futils_readbuffer(&dot_git_content, "submod2/" "sm_libgit2" "/.git"));
	cl_assert_equal_s("gitdir: ../.git/modules/sm_libgit2/", dot_git_content.ptr);

	git_repository_free(repo);
66
	git_buf_dispose(&dot_git_content);
67

68 69 70 71 72 73 74 75 76 77 78 79 80
	/* add a submodule not using a gitlink */

	cl_git_pass(
		git_submodule_add_setup(&sm, g_repo, "https://github.com/libgit2/libgit2.git", "sm_libgit2b", 0)
		);
	git_submodule_free(sm);

	cl_assert(git_path_isdir("submod2/" "sm_libgit2b" "/.git"));
	cl_assert(git_path_isfile("submod2/" "sm_libgit2b" "/.git/HEAD"));
	cl_assert(!git_path_exists("submod2/.git/modules/" "sm_libgit2b"));
	assert_submodule_url("sm_libgit2b", "https://github.com/libgit2/libgit2.git");
}

Russell Belfer committed
81 82
void test_submodule_add__url_relative(void)
{
83 84
	git_submodule *sm;
	git_remote *remote;
85
	git_strarray problems = {0};
Russell Belfer committed
86

87 88
	/* default remote url is https://github.com/libgit2/false.git */
	g_repo = cl_git_sandbox_init("testrepo2");
Russell Belfer committed
89 90

	/* make sure we don't default to origin - rename origin -> test_remote */
91
	cl_git_pass(git_remote_rename(&problems, g_repo, "origin", "test_remote"));
92
	cl_assert_equal_i(0, problems.count);
93
	git_strarray_dispose(&problems);
94
	cl_git_fail(git_remote_lookup(&remote, g_repo, "origin"));
95 96 97 98 99

	cl_git_pass(
		git_submodule_add_setup(&sm, g_repo, "../TestGitRepository", "TestGitRepository", 1)
		);
	git_submodule_free(sm);
Russell Belfer committed
100

101 102 103
	assert_submodule_url("TestGitRepository", "https://github.com/libgit2/TestGitRepository");
}

Russell Belfer committed
104 105
void test_submodule_add__url_relative_to_origin(void)
{
106
	git_submodule *sm;
Russell Belfer committed
107

108 109 110 111 112 113 114
	/* default remote url is https://github.com/libgit2/false.git */
	g_repo = cl_git_sandbox_init("testrepo2");

	cl_git_pass(
		git_submodule_add_setup(&sm, g_repo, "../TestGitRepository", "TestGitRepository", 1)
		);
	git_submodule_free(sm);
Russell Belfer committed
115

116 117 118
	assert_submodule_url("TestGitRepository", "https://github.com/libgit2/TestGitRepository");
}

Russell Belfer committed
119 120
void test_submodule_add__url_relative_to_workdir(void)
{
121 122 123 124 125 126 127 128 129 130
	git_submodule *sm;

	/* In this repo, HEAD (master) has no remote tracking branc h*/
	g_repo = cl_git_sandbox_init("testrepo");

	cl_git_pass(
		git_submodule_add_setup(&sm, g_repo, "./", "TestGitRepository", 1)
		);
	git_submodule_free(sm);

Russell Belfer committed
131
	assert_submodule_url("TestGitRepository", git_repository_workdir(g_repo));
132
}
133

134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
static void test_add_entry(
	git_index *index,
	const char *idstr,
	const char *path,
	git_filemode_t mode)
{
	git_index_entry entry = {{0}};

	cl_git_pass(git_oid_fromstr(&entry.id, idstr));

	entry.path = path;
	entry.mode = mode;

	cl_git_pass(git_index_add(index, &entry));
}

150 151 152 153 154 155 156 157
void test_submodule_add__path_exists_in_index(void)
{
	git_index *index;
	git_submodule *sm;
	git_buf filename = GIT_BUF_INIT;

	g_repo = cl_git_sandbox_init("testrepo");

158
	cl_git_pass(git_buf_joinpath(&filename, "subdirectory", "test.txt"));
159

160
	cl_git_pass(git_repository_index__weakptr(&index, g_repo));
161

162
	test_add_entry(index, valid_blob_id, filename.ptr, GIT_FILEMODE_BLOB);
163

164
	cl_git_fail_with(git_submodule_add_setup(&sm, g_repo, "./", "subdirectory", 1), GIT_EEXISTS);
165

166
	git_submodule_free(sm);
167
	git_buf_dispose(&filename);
168 169 170 171 172 173 174 175 176 177
}

void test_submodule_add__file_exists_in_index(void)
{
	git_index *index;
	git_submodule *sm;
	git_buf name = GIT_BUF_INIT;

	g_repo = cl_git_sandbox_init("testrepo");

178
	cl_git_pass(git_repository_index__weakptr(&index, g_repo));
179

180
	test_add_entry(index, valid_blob_id, "subdirectory", GIT_FILEMODE_BLOB);
181

182
	cl_git_fail_with(git_submodule_add_setup(&sm, g_repo, "./", "subdirectory", 1), GIT_EEXISTS);
183

184
	git_submodule_free(sm);
185
	git_buf_dispose(&name);
186
}
187 188 189 190 191

void test_submodule_add__submodule_clone(void)
{
	git_oid tree_id, commit_id;
	git_signature *sig;
192 193
	git_submodule *sm;
	git_index *index;
194

195
	g_repo = cl_git_sandbox_init("empty_standard_repo");
196 197 198 199 200 201

	/* Create the submodule structure, clone into it and finalize */
	cl_git_pass(git_submodule_add_setup(&sm, g_repo, cl_fixture("testrepo.git"), "testrepo-add", true));
	cl_git_pass(git_submodule_clone(NULL, sm, NULL));
	cl_git_pass(git_submodule_add_finalize(sm));

202
	/* Create the submodule commit */
203 204 205 206
	cl_git_pass(git_repository_index(&index, g_repo));
	cl_git_pass(git_index_write_tree(&tree_id, index));
	cl_git_pass(git_signature_now(&sig, "Submoduler", "submoduler@local"));
	cl_git_pass(git_commit_create_from_ids(&commit_id, g_repo, "HEAD", sig, sig, NULL, "A submodule\n",
207
					       &tree_id, 0, NULL));
208 209

	assert_submodule_exists(g_repo, "testrepo-add");
210 211 212 213

	git_signature_free(sig);
	git_submodule_free(sm);
	git_index_free(index);
214
}
215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251

void test_submodule_add__submodule_clone_into_nonempty_dir_succeeds(void)
{
	git_submodule *sm;

	g_repo = cl_git_sandbox_init("empty_standard_repo");

	cl_git_pass(p_mkdir("empty_standard_repo/sm", 0777));
	cl_git_mkfile("empty_standard_repo/sm/foobar", "");

	/* Create the submodule structure, clone into it and finalize */
	cl_git_pass(git_submodule_add_setup(&sm, g_repo, cl_fixture("testrepo.git"), "sm", true));
	cl_git_pass(git_submodule_clone(NULL, sm, NULL));
	cl_git_pass(git_submodule_add_finalize(sm));

	cl_assert(git_path_exists("empty_standard_repo/sm/foobar"));

	assert_submodule_exists(g_repo, "sm");

	git_submodule_free(sm);
}

void test_submodule_add__submodule_clone_twice_fails(void)
{
	git_submodule *sm;

	g_repo = cl_git_sandbox_init("empty_standard_repo");

	/* Create the submodule structure, clone into it and finalize */
	cl_git_pass(git_submodule_add_setup(&sm, g_repo, cl_fixture("testrepo.git"), "sm", true));
	cl_git_pass(git_submodule_clone(NULL, sm, NULL));
	cl_git_pass(git_submodule_add_finalize(sm));

	cl_git_fail(git_submodule_clone(NULL, sm, NULL));

	git_submodule_free(sm);
}