1 #include "clar_libgit2.h"
3 #include "repository.h"
6 #include "config/config_helpers.h"
9 STANDARD_REPOSITORY
= 0,
13 static git_repository
*_repo
= NULL
;
14 static git_buf _global_path
= GIT_BUF_INIT
;
15 static git_buf _tmp_path
= GIT_BUF_INIT
;
16 static mode_t g_umask
= 0;
18 void test_repo_init__initialize(void)
22 /* load umask if not already loaded */
24 g_umask
= p_umask(022);
25 (void)p_umask(g_umask
);
28 git_libgit2_opts(GIT_OPT_GET_SEARCH_PATH
, GIT_CONFIG_LEVEL_GLOBAL
,
32 void test_repo_init__cleanup(void)
34 git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH
, GIT_CONFIG_LEVEL_GLOBAL
,
36 git_buf_free(&_global_path
);
38 if (_tmp_path
.size
> 0 && git_path_isdir(_tmp_path
.ptr
))
39 git_futils_rmdir_r(_tmp_path
.ptr
, NULL
, GIT_RMDIR_REMOVE_FILES
);
40 git_buf_free(&_tmp_path
);
43 static void cleanup_repository(void *path
)
45 git_repository_free(_repo
);
48 cl_fixture_cleanup((const char *)path
);
51 static void ensure_repository_init(
52 const char *working_directory
,
54 const char *expected_path_repository
,
55 const char *expected_working_directory
)
59 cl_assert(!git_path_isdir(working_directory
));
61 cl_git_pass(git_repository_init(&_repo
, working_directory
, is_bare
));
63 workdir
= git_repository_workdir(_repo
);
64 if (workdir
!= NULL
|| expected_working_directory
!= NULL
) {
66 git__suffixcmp(workdir
, expected_working_directory
) == 0
71 git__suffixcmp(git_repository_path(_repo
), expected_path_repository
) == 0
74 cl_assert(git_repository_is_bare(_repo
) == is_bare
);
78 DWORD fattrs
= GetFileAttributes(git_repository_path(_repo
));
79 cl_assert((fattrs
& FILE_ATTRIBUTE_HIDDEN
) != 0);
83 cl_assert(git_repository_is_empty(_repo
));
86 void test_repo_init__standard_repo(void)
88 cl_set_cleanup(&cleanup_repository
, "testrepo");
89 ensure_repository_init("testrepo/", 0, "testrepo/.git/", "testrepo/");
92 void test_repo_init__standard_repo_noslash(void)
94 cl_set_cleanup(&cleanup_repository
, "testrepo");
95 ensure_repository_init("testrepo", 0, "testrepo/.git/", "testrepo/");
98 void test_repo_init__bare_repo(void)
100 cl_set_cleanup(&cleanup_repository
, "testrepo.git");
101 ensure_repository_init("testrepo.git/", 1, "testrepo.git/", NULL
);
104 void test_repo_init__bare_repo_noslash(void)
106 cl_set_cleanup(&cleanup_repository
, "testrepo.git");
107 ensure_repository_init("testrepo.git", 1, "testrepo.git/", NULL
);
110 void test_repo_init__bare_repo_escaping_current_workdir(void)
112 git_buf path_repository
= GIT_BUF_INIT
;
113 git_buf path_current_workdir
= GIT_BUF_INIT
;
115 cl_git_pass(git_path_prettify_dir(&path_current_workdir
, ".", NULL
));
117 cl_git_pass(git_buf_joinpath(&path_repository
, git_buf_cstr(&path_current_workdir
), "a/b/c"));
118 cl_git_pass(git_futils_mkdir_r(git_buf_cstr(&path_repository
), GIT_DIR_MODE
));
120 /* Change the current working directory */
121 cl_git_pass(chdir(git_buf_cstr(&path_repository
)));
123 /* Initialize a bare repo with a relative path escaping out of the current working directory */
124 cl_git_pass(git_repository_init(&_repo
, "../d/e.git", 1));
125 cl_git_pass(git__suffixcmp(git_repository_path(_repo
), "/a/b/d/e.git/"));
127 git_repository_free(_repo
);
129 /* Open a bare repo with a relative path escaping out of the current working directory */
130 cl_git_pass(git_repository_open(&_repo
, "../d/e.git"));
132 cl_git_pass(chdir(git_buf_cstr(&path_current_workdir
)));
134 git_buf_free(&path_current_workdir
);
135 git_buf_free(&path_repository
);
137 cleanup_repository("a");
140 void test_repo_init__reinit_bare_repo(void)
142 cl_set_cleanup(&cleanup_repository
, "reinit.git");
144 /* Initialize the repository */
145 cl_git_pass(git_repository_init(&_repo
, "reinit.git", 1));
146 git_repository_free(_repo
);
148 /* Reinitialize the repository */
149 cl_git_pass(git_repository_init(&_repo
, "reinit.git", 1));
152 void test_repo_init__reinit_too_recent_bare_repo(void)
156 /* Initialize the repository */
157 cl_git_pass(git_repository_init(&_repo
, "reinit.git", 1));
158 git_repository_config(&config
, _repo
);
161 * Hack the config of the repository to make it look like it has
162 * been created by a recenter version of git/libgit2
164 cl_git_pass(git_config_set_int32(config
, "core.repositoryformatversion", 42));
166 git_config_free(config
);
167 git_repository_free(_repo
);
169 /* Try to reinitialize the repository */
170 cl_git_fail(git_repository_init(&_repo
, "reinit.git", 1));
172 cl_fixture_cleanup("reinit.git");
175 void test_repo_init__additional_templates(void)
177 git_buf path
= GIT_BUF_INIT
;
179 cl_set_cleanup(&cleanup_repository
, "tester");
181 ensure_repository_init("tester", 0, "tester/.git/", "tester/");
184 git_buf_joinpath(&path
, git_repository_path(_repo
), "description"));
185 cl_assert(git_path_isfile(git_buf_cstr(&path
)));
188 git_buf_joinpath(&path
, git_repository_path(_repo
), "info/exclude"));
189 cl_assert(git_path_isfile(git_buf_cstr(&path
)));
192 git_buf_joinpath(&path
, git_repository_path(_repo
), "hooks"));
193 cl_assert(git_path_isdir(git_buf_cstr(&path
)));
194 /* won't confirm specific contents of hooks dir since it may vary */
199 static void assert_config_entry_on_init_bytype(
200 const char *config_key
, int expected_value
, bool is_bare
)
203 int error
, current_value
;
204 const char *repo_path
= is_bare
?
205 "config_entry/test.bare.git" : "config_entry/test.non.bare.git";
207 cl_set_cleanup(&cleanup_repository
, "config_entry");
209 cl_git_pass(git_repository_init(&_repo
, repo_path
, is_bare
));
211 cl_git_pass(git_repository_config(&config
, _repo
));
212 error
= git_config_get_bool(¤t_value
, config
, config_key
);
213 git_config_free(config
);
215 if (expected_value
>= 0) {
216 cl_assert_equal_i(0, error
);
217 cl_assert_equal_i(expected_value
, current_value
);
219 cl_assert_equal_i(expected_value
, error
);
223 static void assert_config_entry_on_init(
224 const char *config_key
, int expected_value
)
226 assert_config_entry_on_init_bytype(config_key
, expected_value
, true);
227 git_repository_free(_repo
);
229 assert_config_entry_on_init_bytype(config_key
, expected_value
, false);
232 void test_repo_init__detect_filemode(void)
234 assert_config_entry_on_init("core.filemode", cl_is_chmod_supported());
237 void test_repo_init__detect_ignorecase(void)
240 bool found_without_match
;
242 cl_git_write2file("testCAPS", "whatever\n", 0, O_CREAT
| O_WRONLY
, 0666);
243 found_without_match
= (p_stat("Testcaps", &st
) == 0);
244 cl_must_pass(p_unlink("testCAPS"));
246 assert_config_entry_on_init(
247 "core.ignorecase", found_without_match
? true : GIT_ENOTFOUND
);
250 void test_repo_init__detect_precompose_unicode_required(void)
253 char *composed
= "ḱṷṓn", *decomposed
= "ḱṷṓn";
257 cl_git_write2file(composed
, "whatever\n", 0, O_CREAT
| O_WRONLY
, 0666);
258 found_with_nfd
= (p_stat(decomposed
, &st
) == 0);
259 cl_must_pass(p_unlink(composed
));
261 assert_config_entry_on_init("core.precomposeunicode", found_with_nfd
);
263 assert_config_entry_on_init("core.precomposeunicode", GIT_ENOTFOUND
);
267 void test_repo_init__reinit_doesnot_overwrite_ignorecase(void)
272 /* Init a new repo */
273 cl_set_cleanup(&cleanup_repository
, "not.overwrite.git");
274 cl_git_pass(git_repository_init(&_repo
, "not.overwrite.git", 1));
276 /* Change the "core.ignorecase" config value to something unlikely */
277 git_repository_config(&config
, _repo
);
278 git_config_set_int32(config
, "core.ignorecase", 42);
279 git_config_free(config
);
280 git_repository_free(_repo
);
283 /* Reinit the repository */
284 cl_git_pass(git_repository_init(&_repo
, "not.overwrite.git", 1));
285 git_repository_config(&config
, _repo
);
287 /* Ensure the "core.ignorecase" config value hasn't been updated */
288 cl_git_pass(git_config_get_int32(¤t_value
, config
, "core.ignorecase"));
289 cl_assert_equal_i(42, current_value
);
291 git_config_free(config
);
294 void test_repo_init__reinit_overwrites_filemode(void)
296 int expected
= cl_is_chmod_supported(), current_value
;
298 /* Init a new repo */
299 cl_set_cleanup(&cleanup_repository
, "overwrite.git");
300 cl_git_pass(git_repository_init(&_repo
, "overwrite.git", 1));
302 /* Change the "core.filemode" config value to something unlikely */
303 cl_repo_set_bool(_repo
, "core.filemode", !expected
);
305 git_repository_free(_repo
);
308 /* Reinit the repository */
309 cl_git_pass(git_repository_init(&_repo
, "overwrite.git", 1));
311 /* Ensure the "core.filemode" config value has been reset */
312 current_value
= cl_repo_get_bool(_repo
, "core.filemode");
313 cl_assert_equal_i(expected
, current_value
);
316 void test_repo_init__sets_logAllRefUpdates_according_to_type_of_repository(void)
318 assert_config_entry_on_init_bytype("core.logallrefupdates", GIT_ENOTFOUND
, true);
319 git_repository_free(_repo
);
320 assert_config_entry_on_init_bytype("core.logallrefupdates", true, false);
323 void test_repo_init__extended_0(void)
325 git_repository_init_options opts
= GIT_REPOSITORY_INIT_OPTIONS_INIT
;
327 /* without MKDIR this should fail */
328 cl_git_fail(git_repository_init_ext(&_repo
, "extended", &opts
));
330 /* make the directory first, then it should succeed */
331 cl_git_pass(git_futils_mkdir("extended", 0775, 0));
332 cl_git_pass(git_repository_init_ext(&_repo
, "extended", &opts
));
334 cl_assert(!git__suffixcmp(git_repository_workdir(_repo
), "/extended/"));
335 cl_assert(!git__suffixcmp(git_repository_path(_repo
), "/extended/.git/"));
336 cl_assert(!git_repository_is_bare(_repo
));
337 cl_assert(git_repository_is_empty(_repo
));
339 cleanup_repository("extended");
342 void test_repo_init__extended_1(void)
347 git_repository_init_options opts
= GIT_REPOSITORY_INIT_OPTIONS_INIT
;
349 opts
.flags
= GIT_REPOSITORY_INIT_MKPATH
|
350 GIT_REPOSITORY_INIT_NO_DOTGIT_DIR
;
351 opts
.mode
= GIT_REPOSITORY_INIT_SHARED_GROUP
;
352 opts
.workdir_path
= "../c_wd";
353 opts
.description
= "Awesomest test repository evah";
354 opts
.initial_head
= "development";
355 opts
.origin_url
= "https://github.com/libgit2/libgit2.git";
357 cl_git_pass(git_repository_init_ext(&_repo
, "root/b/c.git", &opts
));
359 cl_assert(!git__suffixcmp(git_repository_workdir(_repo
), "/c_wd/"));
360 cl_assert(!git__suffixcmp(git_repository_path(_repo
), "/c.git/"));
361 cl_assert(git_path_isfile("root/b/c_wd/.git"));
362 cl_assert(!git_repository_is_bare(_repo
));
363 /* repo will not be counted as empty because we set head to "development" */
364 cl_assert(!git_repository_is_empty(_repo
));
366 cl_git_pass(git_path_lstat(git_repository_path(_repo
), &st
));
367 cl_assert(S_ISDIR(st
.st_mode
));
368 if (cl_is_chmod_supported())
369 cl_assert((S_ISGID
& st
.st_mode
) == S_ISGID
);
371 cl_assert((S_ISGID
& st
.st_mode
) == 0);
373 cl_git_pass(git_reference_lookup(&ref
, _repo
, "HEAD"));
374 cl_assert(git_reference_type(ref
) == GIT_REF_SYMBOLIC
);
375 cl_assert_equal_s("refs/heads/development", git_reference_symbolic_target(ref
));
376 git_reference_free(ref
);
378 cl_git_pass(git_remote_lookup(&remote
, _repo
, "origin"));
379 cl_assert_equal_s("origin", git_remote_name(remote
));
380 cl_assert_equal_s(opts
.origin_url
, git_remote_url(remote
));
381 git_remote_free(remote
);
383 git_repository_free(_repo
);
384 cl_fixture_cleanup("root");
387 void test_repo_init__relative_gitdir(void)
389 git_repository_init_options opts
= GIT_REPOSITORY_INIT_OPTIONS_INIT
;
390 git_buf dot_git_content
= GIT_BUF_INIT
;
392 opts
.workdir_path
= "../c_wd";
394 GIT_REPOSITORY_INIT_MKPATH
|
395 GIT_REPOSITORY_INIT_RELATIVE_GITLINK
|
396 GIT_REPOSITORY_INIT_NO_DOTGIT_DIR
;
398 /* make the directory first, then it should succeed */
399 cl_git_pass(git_repository_init_ext(&_repo
, "root/b/my_repository", &opts
));
401 cl_assert(!git__suffixcmp(git_repository_workdir(_repo
), "root/b/c_wd/"));
402 cl_assert(!git__suffixcmp(git_repository_path(_repo
), "root/b/my_repository/"));
403 cl_assert(!git_repository_is_bare(_repo
));
404 cl_assert(git_repository_is_empty(_repo
));
406 /* Verify that the gitlink and worktree entries are relative */
408 /* Verify worktree */
409 assert_config_entry_value(_repo
, "core.worktree", "../c_wd/");
412 cl_git_pass(git_futils_readbuffer(&dot_git_content
, "root/b/c_wd/.git"));
413 cl_assert_equal_s("gitdir: ../my_repository/", dot_git_content
.ptr
);
415 git_buf_free(&dot_git_content
);
416 cleanup_repository("root");
419 void test_repo_init__relative_gitdir_2(void)
421 git_repository_init_options opts
= GIT_REPOSITORY_INIT_OPTIONS_INIT
;
422 git_buf dot_git_content
= GIT_BUF_INIT
;
423 git_buf full_path
= GIT_BUF_INIT
;
425 cl_git_pass(git_path_prettify(&full_path
, ".", NULL
));
426 cl_git_pass(git_buf_joinpath(&full_path
, full_path
.ptr
, "root/b/c_wd"));
428 opts
.workdir_path
= full_path
.ptr
;
430 GIT_REPOSITORY_INIT_MKPATH
|
431 GIT_REPOSITORY_INIT_RELATIVE_GITLINK
|
432 GIT_REPOSITORY_INIT_NO_DOTGIT_DIR
;
434 /* make the directory first, then it should succeed */
435 cl_git_pass(git_repository_init_ext(&_repo
, "root/b/my_repository", &opts
));
436 git_buf_free(&full_path
);
438 cl_assert(!git__suffixcmp(git_repository_workdir(_repo
), "root/b/c_wd/"));
439 cl_assert(!git__suffixcmp(git_repository_path(_repo
), "root/b/my_repository/"));
440 cl_assert(!git_repository_is_bare(_repo
));
441 cl_assert(git_repository_is_empty(_repo
));
443 /* Verify that the gitlink and worktree entries are relative */
445 /* Verify worktree */
446 assert_config_entry_value(_repo
, "core.worktree", "../c_wd/");
449 cl_git_pass(git_futils_readbuffer(&dot_git_content
, "root/b/c_wd/.git"));
450 cl_assert_equal_s("gitdir: ../my_repository/", dot_git_content
.ptr
);
452 git_buf_free(&dot_git_content
);
453 cleanup_repository("root");
456 #define CLEAR_FOR_CORE_FILEMODE(M) ((M) &= ~0177)
458 static void assert_hooks_match(
459 const char *template_dir
,
460 const char *repo_dir
,
461 const char *hook_path
,
464 git_buf expected
= GIT_BUF_INIT
;
465 git_buf actual
= GIT_BUF_INIT
;
466 struct stat expected_st
, st
;
468 cl_git_pass(git_buf_joinpath(&expected
, template_dir
, hook_path
));
469 cl_git_pass(git_path_lstat(expected
.ptr
, &expected_st
));
471 cl_git_pass(git_buf_joinpath(&actual
, repo_dir
, hook_path
));
472 cl_git_pass(git_path_lstat(actual
.ptr
, &st
));
474 cl_assert(expected_st
.st_size
== st
.st_size
);
476 if (GIT_MODE_TYPE(expected_st
.st_mode
) != GIT_FILEMODE_LINK
) {
477 mode_t expected_mode
=
478 GIT_MODE_TYPE(expected_st
.st_mode
) |
479 (GIT_PERMS_FOR_WRITE(expected_st
.st_mode
) & ~g_umask
);
481 if (!core_filemode
) {
482 CLEAR_FOR_CORE_FILEMODE(expected_mode
);
483 CLEAR_FOR_CORE_FILEMODE(st
.st_mode
);
486 cl_assert_equal_i_fmt(expected_mode
, st
.st_mode
, "%07o");
489 git_buf_free(&expected
);
490 git_buf_free(&actual
);
493 static void assert_mode_seems_okay(
494 const char *base
, const char *path
,
495 git_filemode_t expect_mode
, bool expect_setgid
, bool core_filemode
)
497 git_buf full
= GIT_BUF_INIT
;
500 cl_git_pass(git_buf_joinpath(&full
, base
, path
));
501 cl_git_pass(git_path_lstat(full
.ptr
, &st
));
504 if (!core_filemode
) {
505 CLEAR_FOR_CORE_FILEMODE(expect_mode
);
506 CLEAR_FOR_CORE_FILEMODE(st
.st_mode
);
507 expect_setgid
= false;
511 cl_assert_equal_b(expect_setgid
, (st
.st_mode
& S_ISGID
) != 0);
514 GIT_PERMS_IS_EXEC(expect_mode
), GIT_PERMS_IS_EXEC(st
.st_mode
));
516 cl_assert_equal_i_fmt(
517 GIT_MODE_TYPE(expect_mode
), GIT_MODE_TYPE(st
.st_mode
), "%07o");
520 static const char *template_sandbox(const char *name
)
522 git_buf hooks_path
= GIT_BUF_INIT
, link_path
= GIT_BUF_INIT
,
523 dotfile_path
= GIT_BUF_INIT
;
524 const char *path
= cl_fixture(name
);
526 cl_fixture_sandbox(name
);
528 /* create a symlink from link.sample to update.sample if the filesystem
532 cl_git_pass(git_buf_joinpath(&hooks_path
, name
, "hooks"));
533 cl_git_pass(git_buf_joinpath(&link_path
, hooks_path
.ptr
, "link.sample"));
536 cl_git_mkfile(link_path
.ptr
, "#!/bin/sh\necho hello, world\n");
538 cl_must_pass(symlink("update.sample", link_path
.ptr
));
541 /* create a file starting with a dot */
542 cl_git_pass(git_buf_joinpath(&dotfile_path
, hooks_path
.ptr
, ".dotfile"));
543 cl_git_mkfile(dotfile_path
.ptr
, "something\n");
544 git_buf_free(&dotfile_path
);
546 git_buf_free(&dotfile_path
);
547 git_buf_free(&link_path
);
548 git_buf_free(&hooks_path
);
553 static void configure_templatedir(const char *template_path
)
555 git_buf config_path
= GIT_BUF_INIT
;
556 git_buf config_data
= GIT_BUF_INIT
;
558 cl_git_pass(git_libgit2_opts(GIT_OPT_GET_SEARCH_PATH
,
559 GIT_CONFIG_LEVEL_GLOBAL
, &_tmp_path
));
560 cl_git_pass(git_buf_puts(&_tmp_path
, ".tmp"));
561 cl_git_pass(git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH
,
562 GIT_CONFIG_LEVEL_GLOBAL
, _tmp_path
.ptr
));
564 cl_must_pass(p_mkdir(_tmp_path
.ptr
, 0777));
566 cl_git_pass(git_buf_joinpath(&config_path
, _tmp_path
.ptr
, ".gitconfig"));
568 cl_git_pass(git_buf_printf(&config_data
,
569 "[init]\n\ttemplatedir = \"%s\"\n", template_path
));
571 cl_git_mkfile(config_path
.ptr
, config_data
.ptr
);
573 git_buf_free(&config_path
);
574 git_buf_free(&config_data
);
577 static void validate_templates(git_repository
*repo
, const char *template_path
)
579 git_buf template_description
= GIT_BUF_INIT
;
580 git_buf repo_description
= GIT_BUF_INIT
;
581 git_buf expected
= GIT_BUF_INIT
;
582 git_buf actual
= GIT_BUF_INIT
;
585 cl_git_pass(git_buf_joinpath(&template_description
, template_path
,
587 cl_git_pass(git_buf_joinpath(&repo_description
, git_repository_path(repo
),
590 cl_git_pass(git_futils_readbuffer(&expected
, template_description
.ptr
));
591 cl_git_pass(git_futils_readbuffer(&actual
, repo_description
.ptr
));
593 cl_assert_equal_s(expected
.ptr
, actual
.ptr
);
595 filemode
= cl_repo_get_bool(repo
, "core.filemode");
598 template_path
, git_repository_path(repo
),
599 "hooks/update.sample", filemode
);
602 template_path
, git_repository_path(repo
),
603 "hooks/link.sample", filemode
);
606 template_path
, git_repository_path(repo
),
607 "hooks/.dotfile", filemode
);
609 git_buf_free(&expected
);
610 git_buf_free(&actual
);
611 git_buf_free(&repo_description
);
612 git_buf_free(&template_description
);
615 void test_repo_init__external_templates_specified_in_options(void)
617 git_repository_init_options opts
= GIT_REPOSITORY_INIT_OPTIONS_INIT
;
619 cl_set_cleanup(&cleanup_repository
, "templated.git");
620 template_sandbox("template");
622 opts
.flags
= GIT_REPOSITORY_INIT_MKPATH
| GIT_REPOSITORY_INIT_BARE
|
623 GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE
;
624 opts
.template_path
= "template";
626 cl_git_pass(git_repository_init_ext(&_repo
, "templated.git", &opts
));
628 cl_assert(git_repository_is_bare(_repo
));
630 cl_assert(!git__suffixcmp(git_repository_path(_repo
), "/templated.git/"));
632 validate_templates(_repo
, "template");
633 cl_fixture_cleanup("template");
636 void test_repo_init__external_templates_specified_in_config(void)
638 git_buf template_path
= GIT_BUF_INIT
;
640 git_repository_init_options opts
= GIT_REPOSITORY_INIT_OPTIONS_INIT
;
642 cl_set_cleanup(&cleanup_repository
, "templated.git");
643 template_sandbox("template");
645 cl_git_pass(git_buf_joinpath(&template_path
, clar_sandbox_path(),
648 configure_templatedir(template_path
.ptr
);
650 opts
.flags
= GIT_REPOSITORY_INIT_MKPATH
| GIT_REPOSITORY_INIT_BARE
|
651 GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE
;
653 cl_git_pass(git_repository_init_ext(&_repo
, "templated.git", &opts
));
655 validate_templates(_repo
, "template");
656 cl_fixture_cleanup("template");
658 git_buf_free(&template_path
);
661 void test_repo_init__external_templates_with_leading_dot(void)
663 git_buf template_path
= GIT_BUF_INIT
;
665 git_repository_init_options opts
= GIT_REPOSITORY_INIT_OPTIONS_INIT
;
667 cl_set_cleanup(&cleanup_repository
, "templated.git");
668 template_sandbox("template");
670 cl_must_pass(p_rename("template", ".template_with_leading_dot"));
672 cl_git_pass(git_buf_joinpath(&template_path
, clar_sandbox_path(),
673 ".template_with_leading_dot"));
675 configure_templatedir(template_path
.ptr
);
677 opts
.flags
= GIT_REPOSITORY_INIT_MKPATH
| GIT_REPOSITORY_INIT_BARE
|
678 GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE
;
680 cl_git_pass(git_repository_init_ext(&_repo
, "templated.git", &opts
));
682 validate_templates(_repo
, ".template_with_leading_dot");
683 cl_fixture_cleanup(".template_with_leading_dot");
685 git_buf_free(&template_path
);
688 void test_repo_init__extended_with_template_and_shared_mode(void)
690 git_repository_init_options opts
= GIT_REPOSITORY_INIT_OPTIONS_INIT
;
692 const char *repo_path
= NULL
;
694 cl_set_cleanup(&cleanup_repository
, "init_shared_from_tpl");
695 template_sandbox("template");
697 opts
.flags
= GIT_REPOSITORY_INIT_MKPATH
|
698 GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE
;
699 opts
.template_path
= "template";
700 opts
.mode
= GIT_REPOSITORY_INIT_SHARED_GROUP
;
702 cl_git_pass(git_repository_init_ext(&_repo
, "init_shared_from_tpl", &opts
));
704 cl_assert(!git_repository_is_bare(_repo
));
705 cl_assert(!git__suffixcmp(git_repository_path(_repo
), "/init_shared_from_tpl/.git/"));
707 filemode
= cl_repo_get_bool(_repo
, "core.filemode");
709 repo_path
= git_repository_path(_repo
);
710 assert_mode_seems_okay(repo_path
, "hooks",
711 GIT_FILEMODE_TREE
| GIT_REPOSITORY_INIT_SHARED_GROUP
, true, filemode
);
712 assert_mode_seems_okay(repo_path
, "info",
713 GIT_FILEMODE_TREE
| GIT_REPOSITORY_INIT_SHARED_GROUP
, true, filemode
);
714 assert_mode_seems_okay(repo_path
, "description",
715 GIT_FILEMODE_BLOB
, false, filemode
);
717 validate_templates(_repo
, "template");
719 cl_fixture_cleanup("template");
722 void test_repo_init__can_reinit_an_initialized_repository(void)
724 git_repository
*reinit
;
726 cl_set_cleanup(&cleanup_repository
, "extended");
728 cl_git_pass(git_futils_mkdir("extended", 0775, 0));
729 cl_git_pass(git_repository_init(&_repo
, "extended", false));
731 cl_git_pass(git_repository_init(&reinit
, "extended", false));
733 cl_assert_equal_s(git_repository_path(_repo
), git_repository_path(reinit
));
735 git_repository_free(reinit
);
738 void test_repo_init__init_with_initial_commit(void)
742 cl_set_cleanup(&cleanup_repository
, "committed");
744 /* Initialize the repository */
745 cl_git_pass(git_repository_init(&_repo
, "committed", 0));
747 /* Init will be automatically created when requested for a new repo */
748 cl_git_pass(git_repository_index(&index
, _repo
));
750 /* Create a file so we can commit it
752 * If you are writing code outside the test suite, you can create this
753 * file any way that you like, such as:
754 * FILE *fp = fopen("committed/file.txt", "w");
755 * fputs("some stuff\n", fp);
757 * We like to use the help functions because they do error detection
758 * in a way that's easily compatible with our test suite.
760 cl_git_mkfile("committed/file.txt", "some stuff\n");
762 /* Add file to the index */
763 cl_git_pass(git_index_add_bypath(index
, "file.txt"));
764 cl_git_pass(git_index_write(index
));
766 /* Intentionally not using cl_repo_commit_from_index here so this code
767 * can be used as an example of how an initial commit is typically
768 * made to a repository...
771 /* Make sure we're ready to use git_signature_default :-) */
773 git_config
*cfg
, *local
;
774 cl_git_pass(git_repository_config(&cfg
, _repo
));
775 cl_git_pass(git_config_open_level(&local
, cfg
, GIT_CONFIG_LEVEL_LOCAL
));
776 cl_git_pass(git_config_set_string(local
, "user.name", "Test User"));
777 cl_git_pass(git_config_set_string(local
, "user.email", "t@example.com"));
778 git_config_free(local
);
779 git_config_free(cfg
);
782 /* Create a commit with the new contents of the index */
785 git_oid tree_id
, commit_id
;
788 cl_git_pass(git_signature_default(&sig
, _repo
));
789 cl_git_pass(git_index_write_tree(&tree_id
, index
));
790 cl_git_pass(git_tree_lookup(&tree
, _repo
, &tree_id
));
792 cl_git_pass(git_commit_create_v(
793 &commit_id
, _repo
, "HEAD", sig
, sig
,
794 NULL
, "First", tree
, 0));
797 git_signature_free(sig
);
800 git_index_free(index
);
803 void test_repo_init__at_filesystem_root(void)
805 git_repository
*repo
;
806 const char *sandbox
= clar_sandbox_path();
807 git_buf root
= GIT_BUF_INIT
;
810 if (!cl_is_env_set("GITTEST_INVASIVE_FS_STRUCTURE"))
813 root_len
= git_path_root(sandbox
);
814 cl_assert(root_len
>= 0);
816 git_buf_put(&root
, sandbox
, root_len
+1);
817 git_buf_joinpath(&root
, root
.ptr
, "libgit2_test_dir");
819 cl_assert(!git_path_exists(root
.ptr
));
821 cl_git_pass(git_repository_init(&repo
, root
.ptr
, 0));
822 cl_assert(git_path_isdir(root
.ptr
));
823 cl_git_pass(git_futils_rmdir_r(root
.ptr
, NULL
, GIT_RMDIR_REMOVE_FILES
));
826 git_repository_free(repo
);