]>
git.proxmox.com Git - libgit2.git/blob - tests/index/tests.c
1 #include "clar_libgit2.h"
4 static const size_t index_entry_count
= 109;
5 static const size_t index_entry_count_2
= 1437;
6 #define TEST_INDEX_PATH cl_fixture("testrepo.git/index")
7 #define TEST_INDEX2_PATH cl_fixture("gitgit.index")
8 #define TEST_INDEXBIG_PATH cl_fixture("big.index")
9 #define TEST_INDEXBAD_PATH cl_fixture("bad.index")
20 static struct test_entry test_entries
[] = {
21 {4, "Makefile", 5064, 0x4C3F7F33},
22 {62, "tests/Makefile", 2631, 0x4C3F7F33},
23 {36, "src/index.c", 10014, 0x4C43368D},
24 {6, "git.git-authors", 2709, 0x4C3F7F33},
25 {48, "src/revobject.h", 1448, 0x4C3F7FE2}
29 static void copy_file(const char *src
, const char *dst
)
31 git_buf source_buf
= GIT_BUF_INIT
;
34 cl_git_pass(git_futils_readbuffer(&source_buf
, src
));
36 dst_fd
= git_futils_creat_withpath(dst
, 0777, 0666); /* -V536 */
40 cl_git_pass(p_write(dst_fd
, source_buf
.ptr
, source_buf
.size
));
43 git_buf_free(&source_buf
);
47 static void files_are_equal(const char *a
, const char *b
)
49 git_buf buf_a
= GIT_BUF_INIT
;
50 git_buf buf_b
= GIT_BUF_INIT
;
53 if (git_futils_readbuffer(&buf_a
, a
) < 0)
56 if (git_futils_readbuffer(&buf_b
, b
) < 0) {
61 pass
= (buf_a
.size
== buf_b
.size
&& !memcmp(buf_a
.ptr
, buf_b
.ptr
, buf_a
.size
));
70 /* Fixture setup and teardown */
71 void test_index_tests__initialize(void)
75 void test_index_tests__empty_index(void)
79 cl_git_pass(git_index_open(&index
, "in-memory-index"));
80 cl_assert(index
->on_disk
== 0);
82 cl_assert(git_index_entrycount(index
) == 0);
83 cl_assert(index
->entries
.sorted
);
85 git_index_free(index
);
88 void test_index_tests__default_test_index(void)
92 git_index_entry
**entries
;
94 cl_git_pass(git_index_open(&index
, TEST_INDEX_PATH
));
95 cl_assert(index
->on_disk
);
97 cl_assert(git_index_entrycount(index
) == index_entry_count
);
98 cl_assert(index
->entries
.sorted
);
100 entries
= (git_index_entry
**)index
->entries
.contents
;
102 for (i
= 0; i
< ARRAY_SIZE(test_entries
); ++i
) {
103 git_index_entry
*e
= entries
[test_entries
[i
].index
];
105 cl_assert_equal_s(e
->path
, test_entries
[i
].path
);
106 cl_assert(e
->mtime
.seconds
== test_entries
[i
].mtime
);
107 cl_assert(e
->file_size
== test_entries
[i
].file_size
);
110 git_index_free(index
);
113 void test_index_tests__gitgit_index(void)
117 cl_git_pass(git_index_open(&index
, TEST_INDEX2_PATH
));
118 cl_assert(index
->on_disk
);
120 cl_assert(git_index_entrycount(index
) == index_entry_count_2
);
121 cl_assert(index
->entries
.sorted
);
122 cl_assert(index
->tree
!= NULL
);
124 git_index_free(index
);
127 void test_index_tests__find_in_existing(void)
132 cl_git_pass(git_index_open(&index
, TEST_INDEX_PATH
));
134 for (i
= 0; i
< ARRAY_SIZE(test_entries
); ++i
) {
137 cl_assert(!git_index_find(&idx
, index
, test_entries
[i
].path
));
138 cl_assert(idx
== test_entries
[i
].index
);
141 git_index_free(index
);
144 void test_index_tests__find_in_empty(void)
149 cl_git_pass(git_index_open(&index
, "fake-index"));
151 for (i
= 0; i
< ARRAY_SIZE(test_entries
); ++i
) {
152 cl_assert(GIT_ENOTFOUND
== git_index_find(NULL
, index
, test_entries
[i
].path
));
155 git_index_free(index
);
158 void test_index_tests__write(void)
162 copy_file(TEST_INDEXBIG_PATH
, "index_rewrite");
164 cl_git_pass(git_index_open(&index
, "index_rewrite"));
165 cl_assert(index
->on_disk
);
167 cl_git_pass(git_index_write(index
));
168 files_are_equal(TEST_INDEXBIG_PATH
, "index_rewrite");
170 git_index_free(index
);
172 p_unlink("index_rewrite");
175 void test_index_tests__sort0(void)
177 /* sort the entires in an index */
180 * TODO: This no longer applies:
181 * index sorting in Git uses some specific changes to the way
182 * directories are sorted.
184 * We need to specificially check for this by creating a new
185 * index, adding entries in random order and then
186 * checking for consistency
190 void test_index_tests__sort1(void)
192 /* sort the entires in an empty index */
195 cl_git_pass(git_index_open(&index
, "fake-index"));
197 /* FIXME: this test is slightly dumb */
198 cl_assert(index
->entries
.sorted
);
200 git_index_free(index
);
203 static void cleanup_myrepo(void *opaque
)
206 cl_fixture_cleanup("myrepo");
209 void test_index_tests__add(void)
212 git_filebuf file
= GIT_FILEBUF_INIT
;
213 git_repository
*repo
;
214 const git_index_entry
*entry
;
217 cl_set_cleanup(&cleanup_myrepo
, NULL
);
219 /* Intialize a new repository */
220 cl_git_pass(git_repository_init(&repo
, "./myrepo", 0));
222 /* Ensure we're the only guy in the room */
223 cl_git_pass(git_repository_index(&index
, repo
));
224 cl_assert(git_index_entrycount(index
) == 0);
226 /* Create a new file in the working directory */
227 cl_git_pass(git_futils_mkpath2file("myrepo/test.txt", 0777));
228 cl_git_pass(git_filebuf_open(&file
, "myrepo/test.txt", 0, 0666));
229 cl_git_pass(git_filebuf_write(&file
, "hey there\n", 10));
230 cl_git_pass(git_filebuf_commit(&file
));
232 /* Store the expected hash of the file/blob
233 * This has been generated by executing the following
234 * $ echo "hey there" | git hash-object --stdin
236 cl_git_pass(git_oid_fromstr(&id1
, "a8233120f6ad708f843d861ce2b7228ec4e3dec6"));
238 /* Add the new file to the index */
239 cl_git_pass(git_index_add_bypath(index
, "test.txt"));
241 /* Wow... it worked! */
242 cl_assert(git_index_entrycount(index
) == 1);
243 entry
= git_index_get_byindex(index
, 0);
245 /* And the built-in hashing mechanism worked as expected */
246 cl_assert(git_oid_cmp(&id1
, &entry
->oid
) == 0);
248 /* Test access by path instead of index */
249 cl_assert((entry
= git_index_get_bypath(index
, "test.txt", 0)) != NULL
);
250 cl_assert(git_oid_cmp(&id1
, &entry
->oid
) == 0);
252 git_index_free(index
);
253 git_repository_free(repo
);
256 static void cleanup_1397(void *opaque
)
259 cl_git_sandbox_cleanup();
262 void test_index_tests__add_issue_1397(void)
265 git_repository
*repo
;
266 const git_index_entry
*entry
;
269 cl_set_cleanup(&cleanup_1397
, NULL
);
271 repo
= cl_git_sandbox_init("issue_1397");
273 cl_repo_set_bool(repo
, "core.autocrlf", true);
275 /* Ensure we're the only guy in the room */
276 cl_git_pass(git_repository_index(&index
, repo
));
278 /* Store the expected hash of the file/blob
279 * This has been generated by executing the following
280 * $ git hash-object crlf_file.txt
282 cl_git_pass(git_oid_fromstr(&id1
, "8312e0889a9cbab77c732b6bc39b51a683e3a318"));
284 /* Make sure the initial SHA-1 is correct */
285 cl_assert((entry
= git_index_get_bypath(index
, "crlf_file.txt", 0)) != NULL
);
286 cl_assert_(git_oid_cmp(&id1
, &entry
->oid
) == 0, "first oid check");
288 /* Update the index */
289 cl_git_pass(git_index_add_bypath(index
, "crlf_file.txt"));
291 /* Check the new SHA-1 */
292 cl_assert((entry
= git_index_get_bypath(index
, "crlf_file.txt", 0)) != NULL
);
293 cl_assert_(git_oid_cmp(&id1
, &entry
->oid
) == 0, "second oid check");
295 git_index_free(index
);
298 void test_index_tests__add_bypath_to_a_bare_repository_returns_EBAREPO(void)
300 git_repository
*bare_repo
;
303 cl_git_pass(git_repository_open(&bare_repo
, cl_fixture("testrepo.git")));
304 cl_git_pass(git_repository_index(&index
, bare_repo
));
306 cl_assert_equal_i(GIT_EBAREREPO
, git_index_add_bypath(index
, "test.txt"));
308 git_index_free(index
);
309 git_repository_free(bare_repo
);
312 /* Test that writing an invalid filename fails */
313 void test_index_tests__write_invalid_filename(void)
315 git_repository
*repo
;
319 p_mkdir("read_tree", 0700);
321 cl_git_pass(git_repository_init(&repo
, "./read_tree", 0));
322 cl_git_pass(git_repository_index(&index
, repo
));
324 cl_assert(git_index_entrycount(index
) == 0);
326 cl_git_mkfile("./read_tree/.git/hello", NULL
);
328 cl_git_pass(git_index_add_bypath(index
, ".git/hello"));
331 cl_git_fail(git_index_write_tree(&expected
, index
));
333 git_index_free(index
);
334 git_repository_free(repo
);
336 cl_fixture_cleanup("read_tree");
339 void test_index_tests__remove_entry(void)
341 git_repository
*repo
;
344 p_mkdir("index_test", 0770);
346 cl_git_pass(git_repository_init(&repo
, "index_test", 0));
347 cl_git_pass(git_repository_index(&index
, repo
));
348 cl_assert(git_index_entrycount(index
) == 0);
350 cl_git_mkfile("index_test/hello", NULL
);
351 cl_git_pass(git_index_add_bypath(index
, "hello"));
352 cl_git_pass(git_index_write(index
));
354 cl_git_pass(git_index_read(index
, true)); /* reload */
355 cl_assert(git_index_entrycount(index
) == 1);
356 cl_assert(git_index_get_bypath(index
, "hello", 0) != NULL
);
358 cl_git_pass(git_index_remove(index
, "hello", 0));
359 cl_git_pass(git_index_write(index
));
361 cl_git_pass(git_index_read(index
, true)); /* reload */
362 cl_assert(git_index_entrycount(index
) == 0);
363 cl_assert(git_index_get_bypath(index
, "hello", 0) == NULL
);
365 git_index_free(index
);
366 git_repository_free(repo
);
367 cl_fixture_cleanup("index_test");
370 void test_index_tests__remove_directory(void)
372 git_repository
*repo
;
375 p_mkdir("index_test", 0770);
377 cl_git_pass(git_repository_init(&repo
, "index_test", 0));
378 cl_git_pass(git_repository_index(&index
, repo
));
379 cl_assert_equal_i(0, (int)git_index_entrycount(index
));
381 p_mkdir("index_test/a", 0770);
382 cl_git_mkfile("index_test/a/1.txt", NULL
);
383 cl_git_mkfile("index_test/a/2.txt", NULL
);
384 cl_git_mkfile("index_test/a/3.txt", NULL
);
385 cl_git_mkfile("index_test/b.txt", NULL
);
387 cl_git_pass(git_index_add_bypath(index
, "a/1.txt"));
388 cl_git_pass(git_index_add_bypath(index
, "a/2.txt"));
389 cl_git_pass(git_index_add_bypath(index
, "a/3.txt"));
390 cl_git_pass(git_index_add_bypath(index
, "b.txt"));
391 cl_git_pass(git_index_write(index
));
393 cl_git_pass(git_index_read(index
, true)); /* reload */
394 cl_assert_equal_i(4, (int)git_index_entrycount(index
));
395 cl_assert(git_index_get_bypath(index
, "a/1.txt", 0) != NULL
);
396 cl_assert(git_index_get_bypath(index
, "a/2.txt", 0) != NULL
);
397 cl_assert(git_index_get_bypath(index
, "b.txt", 0) != NULL
);
399 cl_git_pass(git_index_remove(index
, "a/1.txt", 0));
400 cl_git_pass(git_index_write(index
));
402 cl_git_pass(git_index_read(index
, true)); /* reload */
403 cl_assert_equal_i(3, (int)git_index_entrycount(index
));
404 cl_assert(git_index_get_bypath(index
, "a/1.txt", 0) == NULL
);
405 cl_assert(git_index_get_bypath(index
, "a/2.txt", 0) != NULL
);
406 cl_assert(git_index_get_bypath(index
, "b.txt", 0) != NULL
);
408 cl_git_pass(git_index_remove_directory(index
, "a", 0));
409 cl_git_pass(git_index_write(index
));
411 cl_git_pass(git_index_read(index
, true)); /* reload */
412 cl_assert_equal_i(1, (int)git_index_entrycount(index
));
413 cl_assert(git_index_get_bypath(index
, "a/1.txt", 0) == NULL
);
414 cl_assert(git_index_get_bypath(index
, "a/2.txt", 0) == NULL
);
415 cl_assert(git_index_get_bypath(index
, "b.txt", 0) != NULL
);
417 git_index_free(index
);
418 git_repository_free(repo
);
419 cl_fixture_cleanup("index_test");
422 void test_index_tests__preserves_case(void)
424 git_repository
*repo
;
426 const git_index_entry
*entry
;
429 cl_set_cleanup(&cleanup_myrepo
, NULL
);
431 cl_git_pass(git_repository_init(&repo
, "./myrepo", 0));
432 cl_git_pass(git_repository_index(&index
, repo
));
434 index_caps
= git_index_caps(index
);
436 cl_git_rewritefile("myrepo/test.txt", "hey there\n");
437 cl_git_pass(git_index_add_bypath(index
, "test.txt"));
439 cl_git_pass(p_rename("myrepo/test.txt", "myrepo/TEST.txt"));
440 cl_git_rewritefile("myrepo/TEST.txt", "hello again\n");
441 cl_git_pass(git_index_add_bypath(index
, "TEST.txt"));
443 if (index_caps
& GIT_INDEXCAP_IGNORE_CASE
)
444 cl_assert_equal_i(1, (int)git_index_entrycount(index
));
446 cl_assert_equal_i(2, (int)git_index_entrycount(index
));
448 /* Test access by path instead of index */
449 cl_assert((entry
= git_index_get_bypath(index
, "test.txt", 0)) != NULL
);
450 /* The path should *not* have changed without an explicit remove */
451 cl_assert(git__strcmp(entry
->path
, "test.txt") == 0);
453 cl_assert((entry
= git_index_get_bypath(index
, "TEST.txt", 0)) != NULL
);
454 if (index_caps
& GIT_INDEXCAP_IGNORE_CASE
)
455 /* The path should *not* have changed without an explicit remove */
456 cl_assert(git__strcmp(entry
->path
, "test.txt") == 0);
458 cl_assert(git__strcmp(entry
->path
, "TEST.txt") == 0);
460 git_index_free(index
);
461 git_repository_free(repo
);
464 void test_index_tests__elocked(void)
466 git_repository
*repo
;
468 git_filebuf file
= GIT_FILEBUF_INIT
;
469 const git_error
*err
;
472 cl_set_cleanup(&cleanup_myrepo
, NULL
);
474 cl_git_pass(git_repository_init(&repo
, "./myrepo", 0));
475 cl_git_pass(git_repository_index(&index
, repo
));
477 /* Lock the index file so we fail to lock it */
478 cl_git_pass(git_filebuf_open(&file
, index
->index_file_path
, 0, 0666));
479 error
= git_index_write(index
);
480 cl_assert_equal_i(GIT_ELOCKED
, error
);
483 cl_assert_equal_i(err
->klass
, GITERR_INDEX
);
485 git_filebuf_cleanup(&file
);
486 git_index_free(index
);
487 git_repository_free(repo
);
490 void test_index_tests__reload_from_disk(void)
492 git_repository
*repo
;
493 git_index
*read_index
;
494 git_index
*write_index
;
496 cl_set_cleanup(&cleanup_myrepo
, NULL
);
498 cl_git_pass(git_futils_mkdir("./myrepo", NULL
, 0777, GIT_MKDIR_PATH
));
499 cl_git_mkfile("./myrepo/a.txt", "a\n");
500 cl_git_mkfile("./myrepo/b.txt", "b\n");
502 cl_git_pass(git_repository_init(&repo
, "./myrepo", 0));
503 cl_git_pass(git_repository_index(&write_index
, repo
));
504 cl_assert_equal_i(false, write_index
->on_disk
);
506 cl_git_pass(git_index_open(&read_index
, write_index
->index_file_path
));
507 cl_assert_equal_i(false, read_index
->on_disk
);
509 /* Stage two new files agaisnt the write_index */
510 cl_git_pass(git_index_add_bypath(write_index
, "a.txt"));
511 cl_git_pass(git_index_add_bypath(write_index
, "b.txt"));
513 cl_assert_equal_sz(2, git_index_entrycount(write_index
));
515 /* Persist the index changes to disk */
516 cl_git_pass(git_index_write(write_index
));
517 cl_assert_equal_i(true, write_index
->on_disk
);
519 /* Sync the changes back into the read_index */
520 cl_assert_equal_sz(0, git_index_entrycount(read_index
));
522 cl_git_pass(git_index_read(read_index
, true));
523 cl_assert_equal_i(true, read_index
->on_disk
);
525 cl_assert_equal_sz(2, git_index_entrycount(read_index
));
527 /* Remove the index file from the filesystem */
528 cl_git_pass(p_unlink(write_index
->index_file_path
));
530 /* Sync the changes back into the read_index */
531 cl_git_pass(git_index_read(read_index
, true));
532 cl_assert_equal_i(false, read_index
->on_disk
);
533 cl_assert_equal_sz(0, git_index_entrycount(read_index
));
535 git_index_free(read_index
);
536 git_index_free(write_index
);
537 git_repository_free(repo
);
540 void test_index_tests__corrupted_extension(void)
542 /* sort the entires in an empty index */
545 cl_git_fail_with(git_index_open(&index
, TEST_INDEXBAD_PATH
), GIT_ERROR
);