index.c 17.8 KB
Newer Older
1
#include "clar_libgit2.h"
2
#include "checkout_helpers.h"
3 4

#include "git2/checkout.h"
5
#include "fileops.h"
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
#include "repository.h"

static git_repository *g_repo;

void test_checkout_index__initialize(void)
{
	git_tree *tree;

	g_repo = cl_git_sandbox_init("testrepo");

	cl_git_pass(git_repository_head_tree(&tree, g_repo));

	reset_index_to_treeish((git_object *)tree);
	git_tree_free(tree);

	cl_git_rewritefile(
		"./testrepo/.gitattributes",
		"* text eol=lf\n");
}

void test_checkout_index__cleanup(void)
{
	cl_git_sandbox_cleanup();
29 30 31 32

	/* try to remove alternative dir */
	if (git_path_isdir("alternative"))
		git_futils_rmdir_r("alternative", NULL, GIT_RMDIR_REMOVE_FILES);
33 34 35 36 37 38 39 40
}

void test_checkout_index__cannot_checkout_a_bare_repository(void)
{
	test_checkout_index__cleanup();

	g_repo = cl_git_sandbox_init("testrepo.git");

41
	cl_git_fail(git_checkout_index(g_repo, NULL, NULL));
42 43
}

44
void test_checkout_index__can_create_missing_files(void)
45
{
46 47
	git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT;

48 49 50 51
	cl_assert_equal_i(false, git_path_isfile("./testrepo/README"));
	cl_assert_equal_i(false, git_path_isfile("./testrepo/branch_file.txt"));
	cl_assert_equal_i(false, git_path_isfile("./testrepo/new.txt"));

52
	opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
53

54
	cl_git_pass(git_checkout_index(g_repo, NULL, &opts));
55

56 57 58
	check_file_contents("./testrepo/README", "hey there\n");
	check_file_contents("./testrepo/branch_file.txt", "hi\nbye!\n");
	check_file_contents("./testrepo/new.txt", "my new file\n");
59 60
}

61 62
void test_checkout_index__can_remove_untracked_files(void)
{
63 64
	git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT;

65 66 67 68 69 70
	git_futils_mkdir("./testrepo/dir/subdir/subsubdir", NULL, 0755, GIT_MKDIR_PATH);
	cl_git_mkfile("./testrepo/dir/one", "one\n");
	cl_git_mkfile("./testrepo/dir/subdir/two", "two\n");

	cl_assert_equal_i(true, git_path_isdir("./testrepo/dir/subdir/subsubdir"));

71
	opts.checkout_strategy =
72 73
		GIT_CHECKOUT_SAFE_CREATE | GIT_CHECKOUT_REMOVE_UNTRACKED;

74
	cl_git_pass(git_checkout_index(g_repo, NULL, &opts));
75 76 77 78

	cl_assert_equal_i(false, git_path_isdir("./testrepo/dir"));
}

79 80
void test_checkout_index__honor_the_specified_pathspecs(void)
{
81
	git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT;
82 83
	char *entries[] = { "*.txt" };

84 85
	opts.paths.strings = entries;
	opts.paths.count = 1;
86 87 88 89 90

	cl_assert_equal_i(false, git_path_isfile("./testrepo/README"));
	cl_assert_equal_i(false, git_path_isfile("./testrepo/branch_file.txt"));
	cl_assert_equal_i(false, git_path_isfile("./testrepo/new.txt"));

91
	opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
92

93
	cl_git_pass(git_checkout_index(g_repo, NULL, &opts));
94 95

	cl_assert_equal_i(false, git_path_isfile("./testrepo/README"));
96 97
	check_file_contents("./testrepo/branch_file.txt", "hi\nbye!\n");
	check_file_contents("./testrepo/new.txt", "my new file\n");
98 99 100 101
}

void test_checkout_index__honor_the_gitattributes_directives(void)
{
102
	git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT;
103 104 105 106 107
	const char *attributes =
		"branch_file.txt text eol=crlf\n"
		"new.txt text eol=lf\n";

	cl_git_mkfile("./testrepo/.gitattributes", attributes);
108
	cl_repo_set_bool(g_repo, "core.autocrlf", false);
109

110
	opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
111

112
	cl_git_pass(git_checkout_index(g_repo, NULL, &opts));
113

114 115 116
	check_file_contents("./testrepo/README", "hey there\n");
	check_file_contents("./testrepo/new.txt", "my new file\n");
	check_file_contents("./testrepo/branch_file.txt", "hi\r\nbye!\r\n");
117 118 119 120 121
}

void test_checkout_index__honor_coreautocrlf_setting_set_to_true(void)
{
#ifdef GIT_WIN32
122
	git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT;
123 124 125
	const char *expected_readme_text = "hey there\r\n";

	cl_git_pass(p_unlink("./testrepo/.gitattributes"));
126
	cl_repo_set_bool(g_repo, "core.autocrlf", true);
127

128
	opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
129

130
	cl_git_pass(git_checkout_index(g_repo, NULL, &opts));
131

132
	check_file_contents("./testrepo/README", expected_readme_text);
133 134 135 136 137
#endif
}

void test_checkout_index__honor_coresymlinks_setting_set_to_true(void)
{
138 139
	git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT;

140
	cl_repo_set_bool(g_repo, "core.symlinks", true);
141

142
	opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
143

144
	cl_git_pass(git_checkout_index(g_repo, NULL, &opts));
145 146

#ifdef GIT_WIN32
147
	check_file_contents("./testrepo/link_to_new.txt", "new.txt");
148 149 150 151 152 153 154 155 156
#else
	{
		char link_data[1024];
		size_t link_size = 1024;

		link_size = p_readlink("./testrepo/link_to_new.txt", link_data, link_size);
		link_data[link_size] = '\0';
		cl_assert_equal_i(link_size, strlen("new.txt"));
		cl_assert_equal_s(link_data, "new.txt");
157
		check_file_contents("./testrepo/link_to_new.txt", "my new file\n");
158 159 160 161 162 163
	}
#endif
}

void test_checkout_index__honor_coresymlinks_setting_set_to_false(void)
{
164 165
	git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT;

166
	cl_repo_set_bool(g_repo, "core.symlinks", false);
167

168
	opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
169

170
	cl_git_pass(git_checkout_index(g_repo, NULL, &opts));
171

172
	check_file_contents("./testrepo/link_to_new.txt", "new.txt");
173 174
}

175
void test_checkout_index__donot_overwrite_modified_file_by_default(void)
176
{
177 178
	git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT;

179 180
	cl_git_mkfile("./testrepo/new.txt", "This isn't what's stored!");

181 182 183
	/* set this up to not return an error code on conflicts, but it
	 * still will not have permission to overwrite anything...
	 */
184
	opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_ALLOW_CONFLICTS;
185

186
	cl_git_pass(git_checkout_index(g_repo, NULL, &opts));
187

188
	check_file_contents("./testrepo/new.txt", "This isn't what's stored!");
189 190
}

191
void test_checkout_index__can_overwrite_modified_file(void)
192
{
193 194
	git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT;

195 196
	cl_git_mkfile("./testrepo/new.txt", "This isn't what's stored!");

197
	opts.checkout_strategy = GIT_CHECKOUT_FORCE;
198

199
	cl_git_pass(git_checkout_index(g_repo, NULL, &opts));
200

201
	check_file_contents("./testrepo/new.txt", "my new file\n");
202 203 204 205
}

void test_checkout_index__options_disable_filters(void)
{
206 207
	git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT;

208 209
	cl_git_mkfile("./testrepo/.gitattributes", "*.txt text eol=crlf\n");

210 211
	opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
	opts.disable_filters = false;
212

213
	cl_git_pass(git_checkout_index(g_repo, NULL, &opts));
214

215
	check_file_contents("./testrepo/new.txt", "my new file\r\n");
216 217 218

	p_unlink("./testrepo/new.txt");

219 220
	opts.disable_filters = true;
	cl_git_pass(git_checkout_index(g_repo, NULL, &opts));
221

222
	check_file_contents("./testrepo/new.txt", "my new file\n");
223 224 225 226
}

void test_checkout_index__options_dir_modes(void)
{
227
	git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT;
228 229 230
	struct stat st;
	git_oid oid;
	git_commit *commit;
231
	mode_t um;
232

233 234 235
	if (!cl_is_chmod_supported())
		return;

236
	cl_git_pass(git_reference_name_to_id(&oid, g_repo, "refs/heads/dir"));
237 238 239 240
	cl_git_pass(git_commit_lookup(&commit, g_repo, &oid));

	reset_index_to_treeish((git_object *)commit);

241 242
	opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
	opts.dir_mode = 0701;
243

244
	cl_git_pass(git_checkout_index(g_repo, NULL, &opts));
245

246 247 248
	/* umask will influence actual directory creation mode */
	(void)p_umask(um = p_umask(022));

249
	cl_git_pass(p_stat("./testrepo/a", &st));
250
	cl_assert_equal_i_fmt(st.st_mode, (GIT_FILEMODE_TREE | 0701) & ~um, "%07o");
251 252 253

	/* File-mode test, since we're on the 'dir' branch */
	cl_git_pass(p_stat("./testrepo/a/b.txt", &st));
254
	cl_assert_equal_i_fmt(st.st_mode, GIT_FILEMODE_BLOB_EXECUTABLE, "%07o");
255 256 257 258 259 260

	git_commit_free(commit);
}

void test_checkout_index__options_override_file_modes(void)
{
261
	git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT;
262 263
	struct stat st;

264 265 266
	if (!cl_is_chmod_supported())
		return;

267 268
	opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
	opts.file_mode = 0700;
269

270
	cl_git_pass(git_checkout_index(g_repo, NULL, &opts));
271 272

	cl_git_pass(p_stat("./testrepo/new.txt", &st));
Russell Belfer committed
273
	cl_assert_equal_i_fmt(st.st_mode & GIT_MODE_PERMS_MASK, 0700, "%07o");
274 275 276 277
}

void test_checkout_index__options_open_flags(void)
{
278 279
	git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT;

280 281
	cl_git_mkfile("./testrepo/new.txt", "hi\n");

282 283
	opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
	opts.file_open_flags = O_CREAT | O_RDWR | O_APPEND;
284

285 286
	opts.checkout_strategy = GIT_CHECKOUT_FORCE;
	cl_git_pass(git_checkout_index(g_repo, NULL, &opts));
287

288
	check_file_contents("./testrepo/new.txt", "hi\nmy new file\n");
289
}
290

291
struct notify_data {
292 293 294 295
	const char *file;
	const char *sha;
};

296 297 298 299 300 301
static int test_checkout_notify_cb(
	git_checkout_notify_t why,
	const char *path,
	const git_diff_file *baseline,
	const git_diff_file *target,
	const git_diff_file *workdir,
302 303
	void *payload)
{
304
	struct notify_data *expectations = (struct notify_data *)payload;
305

306
	GIT_UNUSED(workdir);
307

308 309 310 311
	cl_assert_equal_i(GIT_CHECKOUT_NOTIFY_CONFLICT, why);
	cl_assert_equal_s(expectations->file, path);
	cl_assert_equal_i(0, git_oid_streq(&baseline->oid, expectations->sha));
	cl_assert_equal_i(0, git_oid_streq(&target->oid, expectations->sha));
312 313 314 315 316 317

	return 0;
}

void test_checkout_index__can_notify_of_skipped_files(void)
{
318
	git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT;
319
	struct notify_data data;
320 321 322 323 324 325 326 327 328 329 330 331

	cl_git_mkfile("./testrepo/new.txt", "This isn't what's stored!");

	/*
	 * $ git ls-tree HEAD
	 * 100644 blob a8233120f6ad708f843d861ce2b7228ec4e3dec6    README
	 * 100644 blob 3697d64be941a53d4ae8f6a271e4e3fa56b022cc    branch_file.txt
	 * 100644 blob a71586c1dfe8a71c6cbf6c129f404c5642ff31bd    new.txt
	 */
	data.file = "new.txt";
	data.sha = "a71586c1dfe8a71c6cbf6c129f404c5642ff31bd";

332
	opts.checkout_strategy =
333
		GIT_CHECKOUT_SAFE_CREATE | GIT_CHECKOUT_ALLOW_CONFLICTS;
334 335 336
	opts.notify_flags = GIT_CHECKOUT_NOTIFY_CONFLICT;
	opts.notify_cb = test_checkout_notify_cb;
	opts.notify_payload = &data;
337

338
	cl_git_pass(git_checkout_index(g_repo, NULL, &opts));
339 340
}

341
static int dont_notify_cb(
342 343 344 345 346
	git_checkout_notify_t why,
	const char *path,
	const git_diff_file *baseline,
	const git_diff_file *target,
	const git_diff_file *workdir,
347 348
	void *payload)
{
349 350 351 352 353
	GIT_UNUSED(why);
	GIT_UNUSED(path);
	GIT_UNUSED(baseline);
	GIT_UNUSED(target);
	GIT_UNUSED(workdir);
354 355 356 357 358 359 360 361 362
	GIT_UNUSED(payload);

	cl_assert(false);

	return 0;
}

void test_checkout_index__wont_notify_of_expected_line_ending_changes(void)
{
363 364
	git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT;

365
	cl_git_pass(p_unlink("./testrepo/.gitattributes"));
366
	cl_repo_set_bool(g_repo, "core.autocrlf", true);
367

368 369
	cl_git_mkfile("./testrepo/new.txt", "my new file\r\n");

370
	opts.checkout_strategy =
371
		GIT_CHECKOUT_SAFE_CREATE | GIT_CHECKOUT_ALLOW_CONFLICTS;
372 373 374
	opts.notify_flags = GIT_CHECKOUT_NOTIFY_CONFLICT;
	opts.notify_cb = dont_notify_cb;
	opts.notify_payload = NULL;
375

376
	cl_git_pass(git_checkout_index(g_repo, NULL, &opts));
377 378
}

379 380
static void checkout_progress_counter(
	const char *path, size_t cur, size_t tot, void *payload)
381
{
Ben Straub committed
382
	GIT_UNUSED(path); GIT_UNUSED(cur); GIT_UNUSED(tot);
383
	(*(int *)payload)++;
384 385 386 387
}

void test_checkout_index__calls_progress_callback(void)
{
388
	git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT;
389 390
	int calls = 0;

391 392 393
	opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
	opts.progress_cb = checkout_progress_counter;
	opts.progress_payload = &calls;
394

395
	cl_git_pass(git_checkout_index(g_repo, NULL, &opts));
396
	cl_assert(calls > 0);
397
}
398 399 400

void test_checkout_index__can_overcome_name_clashes(void)
{
401
	git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT;
402 403 404 405 406 407 408 409 410
	git_index *index;

	cl_git_pass(git_repository_index(&index, g_repo));
	git_index_clear(index);

	cl_git_mkfile("./testrepo/path0", "content\r\n");
	cl_git_pass(p_mkdir("./testrepo/path1", 0777));
	cl_git_mkfile("./testrepo/path1/file1", "content\r\n");

411 412
	cl_git_pass(git_index_add_bypath(index, "path0"));
	cl_git_pass(git_index_add_bypath(index, "path1/file1"));
413

414 415 416 417 418 419 420 421
	cl_git_pass(p_unlink("./testrepo/path0"));
	cl_git_pass(git_futils_rmdir_r(
		"./testrepo/path1", NULL, GIT_RMDIR_REMOVE_FILES));

	cl_git_mkfile("./testrepo/path1", "content\r\n");
	cl_git_pass(p_mkdir("./testrepo/path0", 0777));
	cl_git_mkfile("./testrepo/path0/file0", "content\r\n");

422 423 424
	cl_assert(git_path_isfile("./testrepo/path1"));
	cl_assert(git_path_isfile("./testrepo/path0/file0"));

425
	opts.checkout_strategy =
426
		GIT_CHECKOUT_SAFE_CREATE | GIT_CHECKOUT_ALLOW_CONFLICTS;
427
	cl_git_pass(git_checkout_index(g_repo, index, &opts));
428 429 430 431

	cl_assert(git_path_isfile("./testrepo/path1"));
	cl_assert(git_path_isfile("./testrepo/path0/file0"));

432 433
	opts.checkout_strategy = GIT_CHECKOUT_FORCE;
	cl_git_pass(git_checkout_index(g_repo, index, &opts));
434 435 436 437

	cl_assert(git_path_isfile("./testrepo/path0"));
	cl_assert(git_path_isfile("./testrepo/path1/file1"));

438 439
	git_index_free(index);
}
440 441 442

void test_checkout_index__validates_struct_version(void)
{
443
	git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT;
444 445
	const git_error *err;

446 447
	opts.version = 1024;
	cl_git_fail(git_checkout_index(g_repo, NULL, &opts));
448 449 450 451

	err = giterr_last();
	cl_assert_equal_i(err->klass, GITERR_INVALID);

452
	opts.version = 0;
453
	giterr_clear();
454
	cl_git_fail(git_checkout_index(g_repo, NULL, &opts));
455 456 457 458

	err = giterr_last();
	cl_assert_equal_i(err->klass, GITERR_INVALID);
}
459 460 461 462 463

void test_checkout_index__can_update_prefixed_files(void)
{
	git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT;

464 465 466 467
	cl_assert_equal_i(false, git_path_isfile("./testrepo/README"));
	cl_assert_equal_i(false, git_path_isfile("./testrepo/branch_file.txt"));
	cl_assert_equal_i(false, git_path_isfile("./testrepo/new.txt"));

468 469 470 471 472 473 474
	cl_git_mkfile("./testrepo/READ", "content\n");
	cl_git_mkfile("./testrepo/README.after", "content\n");
	cl_git_pass(p_mkdir("./testrepo/branch_file", 0777));
	cl_git_pass(p_mkdir("./testrepo/branch_file/contained_dir", 0777));
	cl_git_mkfile("./testrepo/branch_file/contained_file", "content\n");
	cl_git_pass(p_mkdir("./testrepo/branch_file.txt.after", 0777));

475 476
	opts.checkout_strategy =
		GIT_CHECKOUT_SAFE_CREATE | GIT_CHECKOUT_REMOVE_UNTRACKED;
477 478 479

	cl_git_pass(git_checkout_index(g_repo, NULL, &opts));

480 481 482
	/* remove untracked will remove the .gitattributes file before the blobs
	 * were created, so they will have had crlf filtering applied on Windows
	 */
483 484 485
	check_file_contents_nocr("./testrepo/README", "hey there\n");
	check_file_contents_nocr("./testrepo/branch_file.txt", "hi\nbye!\n");
	check_file_contents_nocr("./testrepo/new.txt", "my new file\n");
486 487 488 489 490 491

	cl_assert(!git_path_exists("testrepo/READ"));
	cl_assert(!git_path_exists("testrepo/README.after"));
	cl_assert(!git_path_exists("testrepo/branch_file"));
	cl_assert(!git_path_exists("testrepo/branch_file.txt.after"));
}
492 493 494 495 496 497 498 499 500 501

void test_checkout_index__can_checkout_a_newly_initialized_repository(void)
{
	test_checkout_index__cleanup();

	g_repo = cl_git_sandbox_init("empty_standard_repo");
	cl_git_remove_placeholders(git_repository_path(g_repo), "dummy-marker.txt");

	cl_git_pass(git_checkout_index(g_repo, NULL, NULL));
}
502 503 504 505 506 507 508 509 510

void test_checkout_index__issue_1397(void)
{
	git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT;

	test_checkout_index__cleanup();

	g_repo = cl_git_sandbox_init("issue_1397");

Russell Belfer committed
511
	cl_repo_set_bool(g_repo, "core.autocrlf", true);
512 513 514 515 516

	opts.checkout_strategy = GIT_CHECKOUT_FORCE;

	cl_git_pass(git_checkout_index(g_repo, NULL, &opts));

517
	check_file_contents("./issue_1397/crlf_file.txt", "first line\r\nsecond line\r\nboth with crlf");
518
}
519 520 521 522 523 524 525 526 527

void test_checkout_index__target_directory(void)
{
	git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT;
	checkout_counts cts;
	memset(&cts, 0, sizeof(cts));

	opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
	opts.target_directory = "alternative";
528
	cl_assert(!git_path_isdir("alternative"));
529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546

	opts.notify_flags = GIT_CHECKOUT_NOTIFY_ALL;
	opts.notify_cb = checkout_count_callback;
	opts.notify_payload = &cts;

	/* create some files that *would* conflict if we were using the wd */
	cl_git_mkfile("testrepo/README", "I'm in the way!\n");
	cl_git_mkfile("testrepo/new.txt", "my new file\n");

	cl_git_pass(git_checkout_index(g_repo, NULL, &opts));

	cl_assert_equal_i(0, cts.n_untracked);
	cl_assert_equal_i(0, cts.n_ignored);
	cl_assert_equal_i(4, cts.n_updates);

	check_file_contents("./alternative/README", "hey there\n");
	check_file_contents("./alternative/branch_file.txt", "hi\nbye!\n");
	check_file_contents("./alternative/new.txt", "my new file\n");
547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588

	cl_git_pass(git_futils_rmdir_r(
		"alternative", NULL, GIT_RMDIR_REMOVE_FILES));
}

void test_checkout_index__target_directory_from_bare(void)
{
	git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT;
	git_index *index;
	git_object *head = NULL;
	checkout_counts cts;
	memset(&cts, 0, sizeof(cts));

	test_checkout_index__cleanup();

	g_repo = cl_git_sandbox_init("testrepo.git");
	cl_assert(git_repository_is_bare(g_repo));

	cl_git_pass(git_repository_index(&index, g_repo));
	cl_git_pass(git_revparse_single(&head, g_repo, "HEAD^{tree}"));
	cl_git_pass(git_index_read_tree(index, (const git_tree *)head));
	cl_git_pass(git_index_write(index));
	git_index_free(index);

	opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;

	opts.notify_flags = GIT_CHECKOUT_NOTIFY_ALL;
	opts.notify_cb = checkout_count_callback;
	opts.notify_payload = &cts;

	/* fail to checkout a bare repo */
	cl_git_fail(git_checkout_index(g_repo, NULL, &opts));

	opts.target_directory = "alternative";
	cl_assert(!git_path_isdir("alternative"));

	cl_git_pass(git_checkout_index(g_repo, NULL, &opts));

	cl_assert_equal_i(0, cts.n_untracked);
	cl_assert_equal_i(0, cts.n_ignored);
	cl_assert_equal_i(3, cts.n_updates);

589 590 591 592
	/* files will have been filtered if needed, so strip CR */
	check_file_contents_nocr("./alternative/README", "hey there\n");
	check_file_contents_nocr("./alternative/branch_file.txt", "hi\nbye!\n");
	check_file_contents_nocr("./alternative/new.txt", "my new file\n");
593 594 595

	cl_git_pass(git_futils_rmdir_r(
		"alternative", NULL, GIT_RMDIR_REMOVE_FILES));
nulltoken committed
596 597

	git_object_free(head);
598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619
}

void test_checkout_index__can_get_repo_from_index(void)
{
	git_index *index;
	git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT;

	cl_assert_equal_i(false, git_path_isfile("./testrepo/README"));
	cl_assert_equal_i(false, git_path_isfile("./testrepo/branch_file.txt"));
	cl_assert_equal_i(false, git_path_isfile("./testrepo/new.txt"));

	opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;

	cl_git_pass(git_repository_index(&index, g_repo));

	cl_git_pass(git_checkout_index(NULL, index, &opts));

	check_file_contents("./testrepo/README", "hey there\n");
	check_file_contents("./testrepo/branch_file.txt", "hi\nbye!\n");
	check_file_contents("./testrepo/new.txt", "my new file\n");

	git_index_free(index);
620
}