lookup.c 8.72 KB
Newer Older
Russell Belfer committed
1 2
#include "clar_libgit2.h"
#include "submodule_helpers.h"
3
#include "git2/sys/repository.h"
4
#include "fileops.h"
Russell Belfer committed
5 6 7 8 9

static git_repository *g_repo = NULL;

void test_submodule_lookup__initialize(void)
{
10
	g_repo = setup_fixture_submod2();
Russell Belfer committed
11 12 13 14
}

void test_submodule_lookup__simple_lookup(void)
{
15
	assert_submodule_exists(g_repo, "sm_unchanged");
Russell Belfer committed
16 17

	/* lookup pending change in .gitmodules that is not in HEAD */
18
	assert_submodule_exists(g_repo, "sm_added_and_uncommited");
Russell Belfer committed
19

20 21
	/* lookup pending change in .gitmodules that is not in HEAD nor index */
	assert_submodule_exists(g_repo, "sm_gitmodules_only");
22

Russell Belfer committed
23
	/* lookup git repo subdir that is not added as submodule */
24
	refute_submodule_exists(g_repo, "not-submodule", GIT_EEXISTS);
Russell Belfer committed
25 26

	/* lookup existing directory that is not a submodule */
27
	refute_submodule_exists(g_repo, "just_a_dir", GIT_ENOTFOUND);
Russell Belfer committed
28 29

	/* lookup existing file that is not a submodule */
30
	refute_submodule_exists(g_repo, "just_a_file", GIT_ENOTFOUND);
Russell Belfer committed
31 32

	/* lookup non-existent item */
33
	refute_submodule_exists(g_repo, "no_such_file", GIT_ENOTFOUND);
Russell Belfer committed
34 35 36 37 38 39 40 41 42 43 44 45 46
}

void test_submodule_lookup__accessors(void)
{
	git_submodule *sm;
	const char *oid = "480095882d281ed676fe5b863569520e54a7d5c0";

	cl_git_pass(git_submodule_lookup(&sm, g_repo, "sm_unchanged"));
	cl_assert(git_submodule_owner(sm) == g_repo);
	cl_assert_equal_s("sm_unchanged", git_submodule_name(sm));
	cl_assert(git__suffixcmp(git_submodule_path(sm), "sm_unchanged") == 0);
	cl_assert(git__suffixcmp(git_submodule_url(sm), "/submod2_target") == 0);

47 48 49
	cl_assert(git_oid_streq(git_submodule_index_id(sm), oid) == 0);
	cl_assert(git_oid_streq(git_submodule_head_id(sm), oid) == 0);
	cl_assert(git_oid_streq(git_submodule_wd_id(sm), oid) == 0);
Russell Belfer committed
50 51

	cl_assert(git_submodule_ignore(sm) == GIT_SUBMODULE_IGNORE_NONE);
52
	cl_assert(git_submodule_update_strategy(sm) == GIT_SUBMODULE_UPDATE_CHECKOUT);
Russell Belfer committed
53

54 55 56
	git_submodule_free(sm);


Russell Belfer committed
57 58 59
	cl_git_pass(git_submodule_lookup(&sm, g_repo, "sm_changed_head"));
	cl_assert_equal_s("sm_changed_head", git_submodule_name(sm));

60 61 62
	cl_assert(git_oid_streq(git_submodule_index_id(sm), oid) == 0);
	cl_assert(git_oid_streq(git_submodule_head_id(sm), oid) == 0);
	cl_assert(git_oid_streq(git_submodule_wd_id(sm),
Russell Belfer committed
63 64
		"3d9386c507f6b093471a3e324085657a3c2b4247") == 0);

65 66 67
	git_submodule_free(sm);


Russell Belfer committed
68 69 70
	cl_git_pass(git_submodule_lookup(&sm, g_repo, "sm_added_and_uncommited"));
	cl_assert_equal_s("sm_added_and_uncommited", git_submodule_name(sm));

71 72 73
	cl_assert(git_oid_streq(git_submodule_index_id(sm), oid) == 0);
	cl_assert(git_submodule_head_id(sm) == NULL);
	cl_assert(git_oid_streq(git_submodule_wd_id(sm), oid) == 0);
Russell Belfer committed
74

75 76 77
	git_submodule_free(sm);


Russell Belfer committed
78 79 80
	cl_git_pass(git_submodule_lookup(&sm, g_repo, "sm_missing_commits"));
	cl_assert_equal_s("sm_missing_commits", git_submodule_name(sm));

81 82 83
	cl_assert(git_oid_streq(git_submodule_index_id(sm), oid) == 0);
	cl_assert(git_oid_streq(git_submodule_head_id(sm), oid) == 0);
	cl_assert(git_oid_streq(git_submodule_wd_id(sm),
Russell Belfer committed
84
		"5e4963595a9774b90524d35a807169049de8ccad") == 0);
85 86

	git_submodule_free(sm);
Russell Belfer committed
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
}

typedef struct {
	int count;
} sm_lookup_data;

static int sm_lookup_cb(git_submodule *sm, const char *name, void *payload)
{
	sm_lookup_data *data = payload;
	data->count += 1;
	cl_assert_equal_s(git_submodule_name(sm), name);
	return 0;
}

void test_submodule_lookup__foreach(void)
{
	sm_lookup_data data;
	memset(&data, 0, sizeof(data));
	cl_git_pass(git_submodule_foreach(g_repo, sm_lookup_cb, &data));
106
	cl_assert_equal_i(8, data.count);
Russell Belfer committed
107
}
108

109
void test_submodule_lookup__lookup_even_with_unborn_head(void)
110
{
111
	git_reference *head;
112

113
	/* put us on an unborn branch */
114
	cl_git_pass(git_reference_symbolic_create(
115
		&head, g_repo, "HEAD", "refs/heads/garbage", 1, NULL));
116
	git_reference_free(head);
117

118
	test_submodule_lookup__simple_lookup(); /* baseline should still pass */
119 120 121 122 123 124 125 126 127 128 129
}

void test_submodule_lookup__lookup_even_with_missing_index(void)
{
	git_index *idx;

	/* give the repo an empty index */
	cl_git_pass(git_index_new(&idx));
	git_repository_set_index(g_repo, idx);
	git_index_free(idx);

130
	test_submodule_lookup__simple_lookup(); /* baseline should still pass */
131
}
132

133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
static void baseline_tests(void)
{
	/* small baseline that should work even if we change the index or make
	 * commits from the index
	 */
	assert_submodule_exists(g_repo, "sm_unchanged");
	assert_submodule_exists(g_repo, "sm_gitmodules_only");
	refute_submodule_exists(g_repo, "not-submodule", GIT_EEXISTS);
}

static void add_submodule_with_commit(const char *name)
{
	git_submodule *sm;
	git_repository *smrepo;
	git_index *idx;
	git_buf p = GIT_BUF_INIT;

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

	assert_submodule_exists(g_repo, name);

	cl_git_pass(git_submodule_open(&smrepo, sm));
	cl_git_pass(git_repository_index(&idx, smrepo));

	cl_git_pass(git_buf_joinpath(&p, git_repository_workdir(smrepo), "file"));
	cl_git_mkfile(p.ptr, "new file");
	git_buf_free(&p);

	cl_git_pass(git_index_add_bypath(idx, "file"));
	cl_git_pass(git_index_write(idx));
	git_index_free(idx);

	cl_repo_commit_from_index(NULL, smrepo, NULL, 0, "initial commit");
	git_repository_free(smrepo);

	cl_git_pass(git_submodule_add_finalize(sm));

	git_submodule_free(sm);
}

174 175 176
void test_submodule_lookup__just_added(void)
{
	git_submodule *sm;
177
	git_buf snap1 = GIT_BUF_INIT, snap2 = GIT_BUF_INIT;
178
	git_reference *original_head = NULL;
179 180 181

	refute_submodule_exists(g_repo, "sm_just_added", GIT_ENOTFOUND);
	refute_submodule_exists(g_repo, "sm_just_added_2", GIT_ENOTFOUND);
182 183
	refute_submodule_exists(g_repo, "sm_just_added_idx", GIT_ENOTFOUND);
	refute_submodule_exists(g_repo, "sm_just_added_head", GIT_ENOTFOUND);
184 185
	refute_submodule_exists(g_repo, "mismatch_name", GIT_ENOTFOUND);
	refute_submodule_exists(g_repo, "mismatch_path", GIT_ENOTFOUND);
186
	baseline_tests();
187

188
	cl_git_pass(git_futils_readbuffer(&snap1, "submod2/.gitmodules"));
189
	cl_git_pass(git_repository_head(&original_head, g_repo));
190 191 192

	cl_git_pass(git_submodule_add_setup(&sm, g_repo,
		"https://github.com/libgit2/libgit2.git", "sm_just_added", 1));
193 194 195
	git_submodule_free(sm);
	assert_submodule_exists(g_repo, "sm_just_added");

196 197
	cl_git_pass(git_submodule_add_setup(&sm, g_repo,
		"https://github.com/libgit2/libgit2.git", "sm_just_added_2", 1));
198
	assert_submodule_exists(g_repo, "sm_just_added_2");
199
	cl_git_fail(git_submodule_add_finalize(sm)); /* fails if no HEAD */
200 201
	git_submodule_free(sm);

202 203 204 205 206 207 208
	add_submodule_with_commit("sm_just_added_head");
	cl_repo_commit_from_index(NULL, g_repo, NULL, 0, "commit new sm to head");
	assert_submodule_exists(g_repo, "sm_just_added_head");

	add_submodule_with_commit("sm_just_added_idx");
	assert_submodule_exists(g_repo, "sm_just_added_idx");

209
	cl_git_pass(git_futils_readbuffer(&snap2, "submod2/.gitmodules"));
210

211 212 213 214 215
	cl_git_append2file(
		"submod2/.gitmodules",
		"\n[submodule \"mismatch_name\"]\n"
		"\tpath = mismatch_path\n"
		"\turl = https://example.com/example.git\n\n");
216 217 218

	assert_submodule_exists(g_repo, "mismatch_name");
	assert_submodule_exists(g_repo, "mismatch_path");
219 220
	assert_submodule_exists(g_repo, "sm_just_added");
	assert_submodule_exists(g_repo, "sm_just_added_2");
221 222 223
	assert_submodule_exists(g_repo, "sm_just_added_idx");
	assert_submodule_exists(g_repo, "sm_just_added_head");
	baseline_tests();
224 225 226

	cl_git_rewritefile("submod2/.gitmodules", snap2.ptr);
	git_buf_free(&snap2);
227

228 229
	refute_submodule_exists(g_repo, "mismatch_name", GIT_ENOTFOUND);
	refute_submodule_exists(g_repo, "mismatch_path", GIT_ENOTFOUND);
230 231
	assert_submodule_exists(g_repo, "sm_just_added");
	assert_submodule_exists(g_repo, "sm_just_added_2");
232 233 234
	assert_submodule_exists(g_repo, "sm_just_added_idx");
	assert_submodule_exists(g_repo, "sm_just_added_head");
	baseline_tests();
235

236 237
	cl_git_rewritefile("submod2/.gitmodules", snap1.ptr);
	git_buf_free(&snap1);
238

239 240 241 242 243
	refute_submodule_exists(g_repo, "mismatch_name", GIT_ENOTFOUND);
	refute_submodule_exists(g_repo, "mismatch_path", GIT_ENOTFOUND);
	/* note error code change, because add_setup made a repo in the workdir */
	refute_submodule_exists(g_repo, "sm_just_added", GIT_EEXISTS);
	refute_submodule_exists(g_repo, "sm_just_added_2", GIT_EEXISTS);
244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261
	/* these still exist in index and head respectively */
	assert_submodule_exists(g_repo, "sm_just_added_idx");
	assert_submodule_exists(g_repo, "sm_just_added_head");
	baseline_tests();

	{
		git_index *idx;
		cl_git_pass(git_repository_index(&idx, g_repo));
		cl_git_pass(git_index_remove_bypath(idx, "sm_just_added_idx"));
		cl_git_pass(git_index_remove_bypath(idx, "sm_just_added_head"));
		cl_git_pass(git_index_write(idx));
		git_index_free(idx);
	}

	refute_submodule_exists(g_repo, "sm_just_added_idx", GIT_EEXISTS);
	assert_submodule_exists(g_repo, "sm_just_added_head");

	{
262
		cl_git_pass(git_reference_create(NULL, g_repo, "refs/heads/master", git_reference_target(original_head), 1, "move head back"));
263 264 265 266
		git_reference_free(original_head);
	}

	refute_submodule_exists(g_repo, "sm_just_added_head", GIT_EEXISTS);
267
}
268