add.c 7.11 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
static void assert_submodule_url(const char* name, const char *url)
{
20
	git_str key = GIT_STR_INIT;
Russell Belfer committed
21 22


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

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

29 30 31
void test_submodule_add__url_absolute(void)
{
	git_submodule *sm;
32
	git_repository *repo;
33
	git_str dot_git_content = GIT_STR_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
		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);

49
	cl_assert(git_fs_path_isfile("submod2/" "sm_libgit2" "/.git"));
50

51 52 53
	cl_assert(git_fs_path_isdir("submod2/.git/modules"));
	cl_assert(git_fs_path_isdir("submod2/.git/modules/" "sm_libgit2"));
	cl_assert(git_fs_path_isfile("submod2/.git/modules/" "sm_libgit2" "/HEAD"));
54 55
	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_str_dispose(&dot_git_content);
67

68 69 70 71 72 73 74
	/* 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);

75 76 77
	cl_assert(git_fs_path_isdir("submod2/" "sm_libgit2b" "/.git"));
	cl_assert(git_fs_path_isfile("submod2/" "sm_libgit2b" "/.git/HEAD"));
	cl_assert(!git_fs_path_exists("submod2/.git/modules/" "sm_libgit2b"));
78 79 80
	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
void test_submodule_add__path_exists_in_index(void)
{
	git_index *index;
	git_submodule *sm;
154
	git_str filename = GIT_STR_INIT;
155 156 157

	g_repo = cl_git_sandbox_init("testrepo");

158
	cl_git_pass(git_str_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_str_dispose(&filename);
168 169 170 171 172 173
}

void test_submodule_add__file_exists_in_index(void)
{
	git_index *index;
	git_submodule *sm;
174
	git_str name = GIT_STR_INIT;
175 176 177

	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_str_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

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));

230
	cl_assert(git_fs_path_exists("empty_standard_repo/sm/foobar"));
231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251

	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);
}