]> git.proxmox.com Git - libgit2.git/blob - tests/repo/init.c
Merge pull request #2575 from cirosantilli/factor-struct-typedef
[libgit2.git] / tests / repo / init.c
1 #include "clar_libgit2.h"
2 #include "fileops.h"
3 #include "repository.h"
4 #include "config.h"
5 #include "path.h"
6
7 enum repo_mode {
8 STANDARD_REPOSITORY = 0,
9 BARE_REPOSITORY = 1
10 };
11
12 static git_repository *_repo = NULL;
13 static mode_t g_umask = 0;
14
15 void test_repo_init__initialize(void)
16 {
17 _repo = NULL;
18
19 /* load umask if not already loaded */
20 if (!g_umask) {
21 g_umask = p_umask(022);
22 (void)p_umask(g_umask);
23 }
24 }
25
26 static void cleanup_repository(void *path)
27 {
28 git_repository_free(_repo);
29 _repo = NULL;
30
31 cl_fixture_cleanup((const char *)path);
32 }
33
34 static void ensure_repository_init(
35 const char *working_directory,
36 int is_bare,
37 const char *expected_path_repository,
38 const char *expected_working_directory)
39 {
40 const char *workdir;
41
42 cl_assert(!git_path_isdir(working_directory));
43
44 cl_git_pass(git_repository_init(&_repo, working_directory, is_bare));
45
46 workdir = git_repository_workdir(_repo);
47 if (workdir != NULL || expected_working_directory != NULL) {
48 cl_assert(
49 git__suffixcmp(workdir, expected_working_directory) == 0
50 );
51 }
52
53 cl_assert(
54 git__suffixcmp(git_repository_path(_repo), expected_path_repository) == 0
55 );
56
57 cl_assert(git_repository_is_bare(_repo) == is_bare);
58
59 #ifdef GIT_WIN32
60 if (!is_bare) {
61 DWORD fattrs = GetFileAttributes(git_repository_path(_repo));
62 cl_assert((fattrs & FILE_ATTRIBUTE_HIDDEN) != 0);
63 }
64 #endif
65
66 cl_assert(git_repository_is_empty(_repo));
67 }
68
69 void test_repo_init__standard_repo(void)
70 {
71 cl_set_cleanup(&cleanup_repository, "testrepo");
72 ensure_repository_init("testrepo/", 0, "testrepo/.git/", "testrepo/");
73 }
74
75 void test_repo_init__standard_repo_noslash(void)
76 {
77 cl_set_cleanup(&cleanup_repository, "testrepo");
78 ensure_repository_init("testrepo", 0, "testrepo/.git/", "testrepo/");
79 }
80
81 void test_repo_init__bare_repo(void)
82 {
83 cl_set_cleanup(&cleanup_repository, "testrepo.git");
84 ensure_repository_init("testrepo.git/", 1, "testrepo.git/", NULL);
85 }
86
87 void test_repo_init__bare_repo_noslash(void)
88 {
89 cl_set_cleanup(&cleanup_repository, "testrepo.git");
90 ensure_repository_init("testrepo.git", 1, "testrepo.git/", NULL);
91 }
92
93 void test_repo_init__bare_repo_escaping_current_workdir(void)
94 {
95 git_buf path_repository = GIT_BUF_INIT;
96 git_buf path_current_workdir = GIT_BUF_INIT;
97
98 cl_git_pass(git_path_prettify_dir(&path_current_workdir, ".", NULL));
99
100 cl_git_pass(git_buf_joinpath(&path_repository, git_buf_cstr(&path_current_workdir), "a/b/c"));
101 cl_git_pass(git_futils_mkdir_r(git_buf_cstr(&path_repository), NULL, GIT_DIR_MODE));
102
103 /* Change the current working directory */
104 cl_git_pass(chdir(git_buf_cstr(&path_repository)));
105
106 /* Initialize a bare repo with a relative path escaping out of the current working directory */
107 cl_git_pass(git_repository_init(&_repo, "../d/e.git", 1));
108 cl_git_pass(git__suffixcmp(git_repository_path(_repo), "/a/b/d/e.git/"));
109
110 git_repository_free(_repo);
111
112 /* Open a bare repo with a relative path escaping out of the current working directory */
113 cl_git_pass(git_repository_open(&_repo, "../d/e.git"));
114
115 cl_git_pass(chdir(git_buf_cstr(&path_current_workdir)));
116
117 git_buf_free(&path_current_workdir);
118 git_buf_free(&path_repository);
119
120 cleanup_repository("a");
121 }
122
123 void test_repo_init__reinit_bare_repo(void)
124 {
125 cl_set_cleanup(&cleanup_repository, "reinit.git");
126
127 /* Initialize the repository */
128 cl_git_pass(git_repository_init(&_repo, "reinit.git", 1));
129 git_repository_free(_repo);
130
131 /* Reinitialize the repository */
132 cl_git_pass(git_repository_init(&_repo, "reinit.git", 1));
133 }
134
135 void test_repo_init__reinit_too_recent_bare_repo(void)
136 {
137 git_config *config;
138
139 /* Initialize the repository */
140 cl_git_pass(git_repository_init(&_repo, "reinit.git", 1));
141 git_repository_config(&config, _repo);
142
143 /*
144 * Hack the config of the repository to make it look like it has
145 * been created by a recenter version of git/libgit2
146 */
147 cl_git_pass(git_config_set_int32(config, "core.repositoryformatversion", 42));
148
149 git_config_free(config);
150 git_repository_free(_repo);
151
152 /* Try to reinitialize the repository */
153 cl_git_fail(git_repository_init(&_repo, "reinit.git", 1));
154
155 cl_fixture_cleanup("reinit.git");
156 }
157
158 void test_repo_init__additional_templates(void)
159 {
160 git_buf path = GIT_BUF_INIT;
161
162 cl_set_cleanup(&cleanup_repository, "tester");
163
164 ensure_repository_init("tester", 0, "tester/.git/", "tester/");
165
166 cl_git_pass(
167 git_buf_joinpath(&path, git_repository_path(_repo), "description"));
168 cl_assert(git_path_isfile(git_buf_cstr(&path)));
169
170 cl_git_pass(
171 git_buf_joinpath(&path, git_repository_path(_repo), "info/exclude"));
172 cl_assert(git_path_isfile(git_buf_cstr(&path)));
173
174 cl_git_pass(
175 git_buf_joinpath(&path, git_repository_path(_repo), "hooks"));
176 cl_assert(git_path_isdir(git_buf_cstr(&path)));
177 /* won't confirm specific contents of hooks dir since it may vary */
178
179 git_buf_free(&path);
180 }
181
182 static void assert_config_entry_on_init_bytype(
183 const char *config_key, int expected_value, bool is_bare)
184 {
185 git_config *config;
186 int error, current_value;
187 const char *repo_path = is_bare ?
188 "config_entry/test.bare.git" : "config_entry/test.non.bare.git";
189
190 cl_set_cleanup(&cleanup_repository, "config_entry");
191
192 cl_git_pass(git_repository_init(&_repo, repo_path, is_bare));
193
194 cl_git_pass(git_repository_config(&config, _repo));
195 error = git_config_get_bool(&current_value, config, config_key);
196 git_config_free(config);
197
198 if (expected_value >= 0) {
199 cl_assert_equal_i(0, error);
200 cl_assert_equal_i(expected_value, current_value);
201 } else {
202 cl_assert_equal_i(expected_value, error);
203 }
204 }
205
206 static void assert_config_entry_on_init(
207 const char *config_key, int expected_value)
208 {
209 assert_config_entry_on_init_bytype(config_key, expected_value, true);
210 git_repository_free(_repo);
211
212 assert_config_entry_on_init_bytype(config_key, expected_value, false);
213 }
214
215 void test_repo_init__detect_filemode(void)
216 {
217 assert_config_entry_on_init("core.filemode", cl_is_chmod_supported());
218 }
219
220 void test_repo_init__detect_ignorecase(void)
221 {
222 struct stat st;
223 bool found_without_match;
224
225 cl_git_write2file("testCAPS", "whatever\n", 0, O_CREAT | O_WRONLY, 0666);
226 found_without_match = (p_stat("Testcaps", &st) == 0);
227 cl_must_pass(p_unlink("testCAPS"));
228
229 assert_config_entry_on_init(
230 "core.ignorecase", found_without_match ? true : GIT_ENOTFOUND);
231 }
232
233 void test_repo_init__detect_precompose_unicode_required(void)
234 {
235 #ifdef GIT_USE_ICONV
236 char *composed = "ḱṷṓn", *decomposed = "ḱṷṓn";
237 struct stat st;
238 bool found_with_nfd;
239
240 cl_git_write2file(composed, "whatever\n", 0, O_CREAT | O_WRONLY, 0666);
241 found_with_nfd = (p_stat(decomposed, &st) == 0);
242 cl_must_pass(p_unlink(composed));
243
244 assert_config_entry_on_init("core.precomposeunicode", found_with_nfd);
245 #else
246 assert_config_entry_on_init("core.precomposeunicode", GIT_ENOTFOUND);
247 #endif
248 }
249
250 void test_repo_init__reinit_doesnot_overwrite_ignorecase(void)
251 {
252 git_config *config;
253 int current_value;
254
255 /* Init a new repo */
256 cl_set_cleanup(&cleanup_repository, "not.overwrite.git");
257 cl_git_pass(git_repository_init(&_repo, "not.overwrite.git", 1));
258
259 /* Change the "core.ignorecase" config value to something unlikely */
260 git_repository_config(&config, _repo);
261 git_config_set_int32(config, "core.ignorecase", 42);
262 git_config_free(config);
263 git_repository_free(_repo);
264 _repo = NULL;
265
266 /* Reinit the repository */
267 cl_git_pass(git_repository_init(&_repo, "not.overwrite.git", 1));
268 git_repository_config(&config, _repo);
269
270 /* Ensure the "core.ignorecase" config value hasn't been updated */
271 cl_git_pass(git_config_get_int32(&current_value, config, "core.ignorecase"));
272 cl_assert_equal_i(42, current_value);
273
274 git_config_free(config);
275 }
276
277 void test_repo_init__reinit_overwrites_filemode(void)
278 {
279 int expected = cl_is_chmod_supported(), current_value;
280
281 /* Init a new repo */
282 cl_set_cleanup(&cleanup_repository, "overwrite.git");
283 cl_git_pass(git_repository_init(&_repo, "overwrite.git", 1));
284
285 /* Change the "core.filemode" config value to something unlikely */
286 cl_repo_set_bool(_repo, "core.filemode", !expected);
287
288 git_repository_free(_repo);
289 _repo = NULL;
290
291 /* Reinit the repository */
292 cl_git_pass(git_repository_init(&_repo, "overwrite.git", 1));
293
294 /* Ensure the "core.filemode" config value has been reset */
295 current_value = cl_repo_get_bool(_repo, "core.filemode");
296 cl_assert_equal_i(expected, current_value);
297 }
298
299 void test_repo_init__sets_logAllRefUpdates_according_to_type_of_repository(void)
300 {
301 assert_config_entry_on_init_bytype("core.logallrefupdates", GIT_ENOTFOUND, true);
302 git_repository_free(_repo);
303 assert_config_entry_on_init_bytype("core.logallrefupdates", true, false);
304 }
305
306 void test_repo_init__extended_0(void)
307 {
308 git_repository_init_options opts = GIT_REPOSITORY_INIT_OPTIONS_INIT;
309
310 /* without MKDIR this should fail */
311 cl_git_fail(git_repository_init_ext(&_repo, "extended", &opts));
312
313 /* make the directory first, then it should succeed */
314 cl_git_pass(git_futils_mkdir("extended", NULL, 0775, 0));
315 cl_git_pass(git_repository_init_ext(&_repo, "extended", &opts));
316
317 cl_assert(!git__suffixcmp(git_repository_workdir(_repo), "/extended/"));
318 cl_assert(!git__suffixcmp(git_repository_path(_repo), "/extended/.git/"));
319 cl_assert(!git_repository_is_bare(_repo));
320 cl_assert(git_repository_is_empty(_repo));
321
322 cleanup_repository("extended");
323 }
324
325 void test_repo_init__extended_1(void)
326 {
327 git_reference *ref;
328 git_remote *remote;
329 struct stat st;
330 git_repository_init_options opts = GIT_REPOSITORY_INIT_OPTIONS_INIT;
331
332 opts.flags = GIT_REPOSITORY_INIT_MKPATH |
333 GIT_REPOSITORY_INIT_NO_DOTGIT_DIR;
334 opts.mode = GIT_REPOSITORY_INIT_SHARED_GROUP;
335 opts.workdir_path = "../c_wd";
336 opts.description = "Awesomest test repository evah";
337 opts.initial_head = "development";
338 opts.origin_url = "https://github.com/libgit2/libgit2.git";
339
340 cl_git_pass(git_repository_init_ext(&_repo, "root/b/c.git", &opts));
341
342 cl_assert(!git__suffixcmp(git_repository_workdir(_repo), "/c_wd/"));
343 cl_assert(!git__suffixcmp(git_repository_path(_repo), "/c.git/"));
344 cl_assert(git_path_isfile("root/b/c_wd/.git"));
345 cl_assert(!git_repository_is_bare(_repo));
346 /* repo will not be counted as empty because we set head to "development" */
347 cl_assert(!git_repository_is_empty(_repo));
348
349 cl_git_pass(git_path_lstat(git_repository_path(_repo), &st));
350 cl_assert(S_ISDIR(st.st_mode));
351 if (cl_is_chmod_supported())
352 cl_assert((S_ISGID & st.st_mode) == S_ISGID);
353 else
354 cl_assert((S_ISGID & st.st_mode) == 0);
355
356 cl_git_pass(git_reference_lookup(&ref, _repo, "HEAD"));
357 cl_assert(git_reference_type(ref) == GIT_REF_SYMBOLIC);
358 cl_assert_equal_s("refs/heads/development", git_reference_symbolic_target(ref));
359 git_reference_free(ref);
360
361 cl_git_pass(git_remote_load(&remote, _repo, "origin"));
362 cl_assert_equal_s("origin", git_remote_name(remote));
363 cl_assert_equal_s(opts.origin_url, git_remote_url(remote));
364 git_remote_free(remote);
365
366 git_repository_free(_repo);
367 cl_fixture_cleanup("root");
368 }
369
370 void test_repo_init__relative_gitdir(void)
371 {
372 git_repository_init_options opts = GIT_REPOSITORY_INIT_OPTIONS_INIT;
373 git_config *cfg;
374 const char *worktree_path;
375 git_buf dot_git_content = GIT_BUF_INIT;
376
377 opts.workdir_path = "../c_wd";
378 opts.flags =
379 GIT_REPOSITORY_INIT_MKPATH |
380 GIT_REPOSITORY_INIT_RELATIVE_GITLINK |
381 GIT_REPOSITORY_INIT_NO_DOTGIT_DIR;
382
383 /* make the directory first, then it should succeed */
384 cl_git_pass(git_repository_init_ext(&_repo, "root/b/my_repository", &opts));
385
386 cl_assert(!git__suffixcmp(git_repository_workdir(_repo), "root/b/c_wd/"));
387 cl_assert(!git__suffixcmp(git_repository_path(_repo), "root/b/my_repository/"));
388 cl_assert(!git_repository_is_bare(_repo));
389 cl_assert(git_repository_is_empty(_repo));
390
391 /* Verify that the gitlink and worktree entries are relative */
392
393 /* Verify worktree */
394 cl_git_pass(git_repository_config(&cfg, _repo));
395 cl_git_pass(git_config_get_string(&worktree_path, cfg, "core.worktree"));
396 cl_assert_equal_s("../c_wd/", worktree_path);
397
398 /* Verify gitlink */
399 cl_git_pass(git_futils_readbuffer(&dot_git_content, "root/b/c_wd/.git"));
400 cl_assert_equal_s("gitdir: ../my_repository/", dot_git_content.ptr);
401
402 git_buf_free(&dot_git_content);
403 git_config_free(cfg);
404 cleanup_repository("root");
405 }
406
407 void test_repo_init__relative_gitdir_2(void)
408 {
409 git_repository_init_options opts = GIT_REPOSITORY_INIT_OPTIONS_INIT;
410 git_config *cfg;
411 const char *worktree_path;
412 git_buf dot_git_content = GIT_BUF_INIT;
413 git_buf full_path = GIT_BUF_INIT;
414
415 cl_git_pass(git_path_prettify(&full_path, ".", NULL));
416 cl_git_pass(git_buf_joinpath(&full_path, full_path.ptr, "root/b/c_wd"));
417
418 opts.workdir_path = full_path.ptr;
419 opts.flags =
420 GIT_REPOSITORY_INIT_MKPATH |
421 GIT_REPOSITORY_INIT_RELATIVE_GITLINK |
422 GIT_REPOSITORY_INIT_NO_DOTGIT_DIR;
423
424 /* make the directory first, then it should succeed */
425 cl_git_pass(git_repository_init_ext(&_repo, "root/b/my_repository", &opts));
426 git_buf_free(&full_path);
427
428 cl_assert(!git__suffixcmp(git_repository_workdir(_repo), "root/b/c_wd/"));
429 cl_assert(!git__suffixcmp(git_repository_path(_repo), "root/b/my_repository/"));
430 cl_assert(!git_repository_is_bare(_repo));
431 cl_assert(git_repository_is_empty(_repo));
432
433 /* Verify that the gitlink and worktree entries are relative */
434
435 /* Verify worktree */
436 cl_git_pass(git_repository_config(&cfg, _repo));
437 cl_git_pass(git_config_get_string(&worktree_path, cfg, "core.worktree"));
438 cl_assert_equal_s("../c_wd/", worktree_path);
439
440 /* Verify gitlink */
441 cl_git_pass(git_futils_readbuffer(&dot_git_content, "root/b/c_wd/.git"));
442 cl_assert_equal_s("gitdir: ../my_repository/", dot_git_content.ptr);
443
444 git_buf_free(&dot_git_content);
445 git_config_free(cfg);
446 cleanup_repository("root");
447 }
448
449 #define CLEAR_FOR_CORE_FILEMODE(M) ((M) &= ~0177)
450
451 static void assert_hooks_match(
452 const char *template_dir,
453 const char *repo_dir,
454 const char *hook_path,
455 bool core_filemode)
456 {
457 git_buf expected = GIT_BUF_INIT;
458 git_buf actual = GIT_BUF_INIT;
459 struct stat expected_st, st;
460
461 cl_git_pass(git_buf_joinpath(&expected, template_dir, hook_path));
462 cl_git_pass(git_path_lstat(expected.ptr, &expected_st));
463
464 cl_git_pass(git_buf_joinpath(&actual, repo_dir, hook_path));
465 cl_git_pass(git_path_lstat(actual.ptr, &st));
466
467 cl_assert(expected_st.st_size == st.st_size);
468
469 if (GIT_MODE_TYPE(expected_st.st_mode) != GIT_FILEMODE_LINK) {
470 mode_t expected_mode =
471 GIT_MODE_TYPE(expected_st.st_mode) |
472 (GIT_PERMS_FOR_WRITE(expected_st.st_mode) & ~g_umask);
473
474 if (!core_filemode) {
475 CLEAR_FOR_CORE_FILEMODE(expected_mode);
476 CLEAR_FOR_CORE_FILEMODE(st.st_mode);
477 }
478
479 cl_assert_equal_i_fmt(expected_mode, st.st_mode, "%07o");
480 }
481
482 git_buf_free(&expected);
483 git_buf_free(&actual);
484 }
485
486 static void assert_mode_seems_okay(
487 const char *base, const char *path,
488 git_filemode_t expect_mode, bool expect_setgid, bool core_filemode)
489 {
490 git_buf full = GIT_BUF_INIT;
491 struct stat st;
492
493 cl_git_pass(git_buf_joinpath(&full, base, path));
494 cl_git_pass(git_path_lstat(full.ptr, &st));
495 git_buf_free(&full);
496
497 if (!core_filemode) {
498 CLEAR_FOR_CORE_FILEMODE(expect_mode);
499 CLEAR_FOR_CORE_FILEMODE(st.st_mode);
500 expect_setgid = false;
501 }
502
503 if (S_ISGID != 0)
504 cl_assert_equal_b(expect_setgid, (st.st_mode & S_ISGID) != 0);
505
506 cl_assert_equal_b(
507 GIT_PERMS_IS_EXEC(expect_mode), GIT_PERMS_IS_EXEC(st.st_mode));
508
509 cl_assert_equal_i_fmt(
510 GIT_MODE_TYPE(expect_mode), GIT_MODE_TYPE(st.st_mode), "%07o");
511 }
512
513 void test_repo_init__extended_with_template(void)
514 {
515 git_buf expected = GIT_BUF_INIT;
516 git_buf actual = GIT_BUF_INIT;
517 git_repository_init_options opts = GIT_REPOSITORY_INIT_OPTIONS_INIT;
518 int filemode;
519
520 cl_set_cleanup(&cleanup_repository, "templated.git");
521
522 opts.flags = GIT_REPOSITORY_INIT_MKPATH | GIT_REPOSITORY_INIT_BARE |
523 GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE;
524 opts.template_path = cl_fixture("template");
525
526 cl_git_pass(git_repository_init_ext(&_repo, "templated.git", &opts));
527
528 cl_assert(git_repository_is_bare(_repo));
529
530 cl_assert(!git__suffixcmp(git_repository_path(_repo), "/templated.git/"));
531
532 cl_git_pass(git_futils_readbuffer(
533 &expected, cl_fixture("template/description")));
534 cl_git_pass(git_futils_readbuffer(
535 &actual, "templated.git/description"));
536
537 cl_assert_equal_s(expected.ptr, actual.ptr);
538
539 git_buf_free(&expected);
540 git_buf_free(&actual);
541
542 filemode = cl_repo_get_bool(_repo, "core.filemode");
543
544 assert_hooks_match(
545 cl_fixture("template"), git_repository_path(_repo),
546 "hooks/update.sample", filemode);
547
548 assert_hooks_match(
549 cl_fixture("template"), git_repository_path(_repo),
550 "hooks/link.sample", filemode);
551 }
552
553 void test_repo_init__extended_with_template_and_shared_mode(void)
554 {
555 git_buf expected = GIT_BUF_INIT;
556 git_buf actual = GIT_BUF_INIT;
557 git_repository_init_options opts = GIT_REPOSITORY_INIT_OPTIONS_INIT;
558 int filemode = true;
559 const char *repo_path = NULL;
560
561 cl_set_cleanup(&cleanup_repository, "init_shared_from_tpl");
562
563 opts.flags = GIT_REPOSITORY_INIT_MKPATH |
564 GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE;
565 opts.template_path = cl_fixture("template");
566 opts.mode = GIT_REPOSITORY_INIT_SHARED_GROUP;
567
568 cl_git_pass(git_repository_init_ext(&_repo, "init_shared_from_tpl", &opts));
569
570 cl_assert(!git_repository_is_bare(_repo));
571 cl_assert(!git__suffixcmp(git_repository_path(_repo), "/init_shared_from_tpl/.git/"));
572
573 filemode = cl_repo_get_bool(_repo, "core.filemode");
574
575 cl_git_pass(git_futils_readbuffer(
576 &expected, cl_fixture("template/description")));
577 cl_git_pass(git_futils_readbuffer(
578 &actual, "init_shared_from_tpl/.git/description"));
579
580 cl_assert_equal_s(expected.ptr, actual.ptr);
581
582 git_buf_free(&expected);
583 git_buf_free(&actual);
584
585 repo_path = git_repository_path(_repo);
586 assert_mode_seems_okay(repo_path, "hooks",
587 GIT_FILEMODE_TREE | GIT_REPOSITORY_INIT_SHARED_GROUP, true, filemode);
588 assert_mode_seems_okay(repo_path, "info",
589 GIT_FILEMODE_TREE | GIT_REPOSITORY_INIT_SHARED_GROUP, true, filemode);
590 assert_mode_seems_okay(repo_path, "description",
591 GIT_FILEMODE_BLOB, false, filemode);
592
593 /* for a non-symlinked hook, it should have shared permissions now */
594 assert_hooks_match(
595 cl_fixture("template"), git_repository_path(_repo),
596 "hooks/update.sample", filemode);
597
598 /* for a symlinked hook, the permissions still should match the
599 * source link, not the GIT_REPOSITORY_INIT_SHARED_GROUP value
600 */
601 assert_hooks_match(
602 cl_fixture("template"), git_repository_path(_repo),
603 "hooks/link.sample", filemode);
604 }
605
606 void test_repo_init__can_reinit_an_initialized_repository(void)
607 {
608 git_repository *reinit;
609
610 cl_set_cleanup(&cleanup_repository, "extended");
611
612 cl_git_pass(git_futils_mkdir("extended", NULL, 0775, 0));
613 cl_git_pass(git_repository_init(&_repo, "extended", false));
614
615 cl_git_pass(git_repository_init(&reinit, "extended", false));
616
617 cl_assert_equal_s(git_repository_path(_repo), git_repository_path(reinit));
618
619 git_repository_free(reinit);
620 }
621
622 void test_repo_init__init_with_initial_commit(void)
623 {
624 git_index *index;
625
626 cl_set_cleanup(&cleanup_repository, "committed");
627
628 /* Initialize the repository */
629 cl_git_pass(git_repository_init(&_repo, "committed", 0));
630
631 /* Init will be automatically created when requested for a new repo */
632 cl_git_pass(git_repository_index(&index, _repo));
633
634 /* Create a file so we can commit it
635 *
636 * If you are writing code outside the test suite, you can create this
637 * file any way that you like, such as:
638 * FILE *fp = fopen("committed/file.txt", "w");
639 * fputs("some stuff\n", fp);
640 * fclose(fp);
641 * We like to use the help functions because they do error detection
642 * in a way that's easily compatible with our test suite.
643 */
644 cl_git_mkfile("committed/file.txt", "some stuff\n");
645
646 /* Add file to the index */
647 cl_git_pass(git_index_add_bypath(index, "file.txt"));
648 cl_git_pass(git_index_write(index));
649
650 /* Intentionally not using cl_repo_commit_from_index here so this code
651 * can be used as an example of how an initial commit is typically
652 * made to a repository...
653 */
654
655 /* Make sure we're ready to use git_signature_default :-) */
656 {
657 git_config *cfg, *local;
658 cl_git_pass(git_repository_config(&cfg, _repo));
659 cl_git_pass(git_config_open_level(&local, cfg, GIT_CONFIG_LEVEL_LOCAL));
660 cl_git_pass(git_config_set_string(local, "user.name", "Test User"));
661 cl_git_pass(git_config_set_string(local, "user.email", "t@example.com"));
662 git_config_free(local);
663 git_config_free(cfg);
664 }
665
666 /* Create a commit with the new contents of the index */
667 {
668 git_signature *sig;
669 git_oid tree_id, commit_id;
670 git_tree *tree;
671
672 cl_git_pass(git_signature_default(&sig, _repo));
673 cl_git_pass(git_index_write_tree(&tree_id, index));
674 cl_git_pass(git_tree_lookup(&tree, _repo, &tree_id));
675
676 cl_git_pass(git_commit_create_v(
677 &commit_id, _repo, "HEAD", sig, sig,
678 NULL, "First", tree, 0));
679
680 git_tree_free(tree);
681 git_signature_free(sig);
682 }
683
684 git_index_free(index);
685 }