]> git.proxmox.com Git - libgit2.git/blob - tests/repo/init.c
New upstream version 1.4.3+dfsg.1
[libgit2.git] / tests / repo / init.c
1 #include "clar_libgit2.h"
2 #include "futils.h"
3 #include "repository.h"
4 #include "config.h"
5 #include "path.h"
6 #include "config/config_helpers.h"
7 #include "repo/repo_helpers.h"
8
9 enum repo_mode {
10 STANDARD_REPOSITORY = 0,
11 BARE_REPOSITORY = 1
12 };
13
14 static git_repository *g_repo = NULL;
15 static git_str g_global_path = GIT_STR_INIT;
16
17 void test_repo_init__initialize(void)
18 {
19 g_repo = NULL;
20
21 git_libgit2_opts(GIT_OPT_GET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL,
22 &g_global_path);
23 }
24
25 void test_repo_init__cleanup(void)
26 {
27 git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL,
28 g_global_path.ptr);
29 git_str_dispose(&g_global_path);
30
31 cl_fixture_cleanup("tmp_global_path");
32 }
33
34 static void cleanup_repository(void *path)
35 {
36 git_repository_free(g_repo);
37 g_repo = NULL;
38
39 cl_fixture_cleanup((const char *)path);
40 }
41
42 static void ensure_repository_init(
43 const char *working_directory,
44 int is_bare,
45 const char *expected_path_repository,
46 const char *expected_working_directory)
47 {
48 const char *workdir;
49
50 cl_assert(!git_fs_path_isdir(working_directory));
51
52 cl_git_pass(git_repository_init(&g_repo, working_directory, is_bare));
53
54 workdir = git_repository_workdir(g_repo);
55 if (workdir != NULL || expected_working_directory != NULL) {
56 cl_assert(
57 git__suffixcmp(workdir, expected_working_directory) == 0
58 );
59 }
60
61 cl_assert(
62 git__suffixcmp(git_repository_path(g_repo), expected_path_repository) == 0
63 );
64
65 cl_assert(git_repository_is_bare(g_repo) == is_bare);
66
67 #ifdef GIT_WIN32
68 if (!is_bare) {
69 DWORD fattrs = GetFileAttributes(git_repository_path(g_repo));
70 cl_assert((fattrs & FILE_ATTRIBUTE_HIDDEN) != 0);
71 }
72 #endif
73
74 cl_assert(git_repository_is_empty(g_repo));
75 }
76
77 void test_repo_init__standard_repo(void)
78 {
79 cl_set_cleanup(&cleanup_repository, "testrepo");
80 ensure_repository_init("testrepo/", 0, "testrepo/.git/", "testrepo/");
81 }
82
83 void test_repo_init__standard_repo_noslash(void)
84 {
85 cl_set_cleanup(&cleanup_repository, "testrepo");
86 ensure_repository_init("testrepo", 0, "testrepo/.git/", "testrepo/");
87 }
88
89 void test_repo_init__bare_repo(void)
90 {
91 cl_set_cleanup(&cleanup_repository, "testrepo.git");
92 ensure_repository_init("testrepo.git/", 1, "testrepo.git/", NULL);
93 }
94
95 void test_repo_init__bare_repo_noslash(void)
96 {
97 cl_set_cleanup(&cleanup_repository, "testrepo.git");
98 ensure_repository_init("testrepo.git", 1, "testrepo.git/", NULL);
99 }
100
101 void test_repo_init__bare_repo_escaping_current_workdir(void)
102 {
103 git_str path_repository = GIT_STR_INIT;
104 git_str path_current_workdir = GIT_STR_INIT;
105
106 cl_git_pass(git_fs_path_prettify_dir(&path_current_workdir, ".", NULL));
107
108 cl_git_pass(git_str_joinpath(&path_repository, git_str_cstr(&path_current_workdir), "a/b/c"));
109 cl_git_pass(git_futils_mkdir_r(git_str_cstr(&path_repository), GIT_DIR_MODE));
110
111 /* Change the current working directory */
112 cl_git_pass(chdir(git_str_cstr(&path_repository)));
113
114 /* Initialize a bare repo with a relative path escaping out of the current working directory */
115 cl_git_pass(git_repository_init(&g_repo, "../d/e.git", 1));
116 cl_git_pass(git__suffixcmp(git_repository_path(g_repo), "/a/b/d/e.git/"));
117
118 git_repository_free(g_repo);
119 g_repo = NULL;
120
121 /* Open a bare repo with a relative path escaping out of the current working directory */
122 cl_git_pass(git_repository_open(&g_repo, "../d/e.git"));
123
124 cl_git_pass(chdir(git_str_cstr(&path_current_workdir)));
125
126 git_str_dispose(&path_current_workdir);
127 git_str_dispose(&path_repository);
128
129 cleanup_repository("a");
130 }
131
132 void test_repo_init__reinit_bare_repo(void)
133 {
134 cl_set_cleanup(&cleanup_repository, "reinit.git");
135
136 /* Initialize the repository */
137 cl_git_pass(git_repository_init(&g_repo, "reinit.git", 1));
138 git_repository_free(g_repo);
139 g_repo = NULL;
140
141 /* Reinitialize the repository */
142 cl_git_pass(git_repository_init(&g_repo, "reinit.git", 1));
143 }
144
145 void test_repo_init__reinit_too_recent_bare_repo(void)
146 {
147 git_config *config;
148
149 /* Initialize the repository */
150 cl_git_pass(git_repository_init(&g_repo, "reinit.git", 1));
151 git_repository_config(&config, g_repo);
152
153 /*
154 * Hack the config of the repository to make it look like it has
155 * been created by a recenter version of git/libgit2
156 */
157 cl_git_pass(git_config_set_int32(config, "core.repositoryformatversion", 42));
158
159 git_config_free(config);
160 git_repository_free(g_repo);
161 g_repo = NULL;
162
163 /* Try to reinitialize the repository */
164 cl_git_fail(git_repository_init(&g_repo, "reinit.git", 1));
165
166 cl_fixture_cleanup("reinit.git");
167 }
168
169 void test_repo_init__additional_templates(void)
170 {
171 git_str path = GIT_STR_INIT;
172
173 cl_set_cleanup(&cleanup_repository, "tester");
174
175 ensure_repository_init("tester", 0, "tester/.git/", "tester/");
176
177 cl_git_pass(
178 git_str_joinpath(&path, git_repository_path(g_repo), "description"));
179 cl_assert(git_fs_path_isfile(git_str_cstr(&path)));
180
181 cl_git_pass(
182 git_str_joinpath(&path, git_repository_path(g_repo), "info/exclude"));
183 cl_assert(git_fs_path_isfile(git_str_cstr(&path)));
184
185 cl_git_pass(
186 git_str_joinpath(&path, git_repository_path(g_repo), "hooks"));
187 cl_assert(git_fs_path_isdir(git_str_cstr(&path)));
188 /* won't confirm specific contents of hooks dir since it may vary */
189
190 git_str_dispose(&path);
191 }
192
193 static void assert_config_entry_on_init_bytype(
194 const char *config_key, int expected_value, bool is_bare)
195 {
196 git_config *config;
197 int error, current_value;
198 const char *repo_path = is_bare ?
199 "config_entry/test.bare.git" : "config_entry/test.non.bare.git";
200
201 cl_set_cleanup(&cleanup_repository, "config_entry");
202
203 cl_git_pass(git_repository_init(&g_repo, repo_path, is_bare));
204
205 cl_git_pass(git_repository_config(&config, g_repo));
206 error = git_config_get_bool(&current_value, config, config_key);
207 git_config_free(config);
208
209 if (expected_value >= 0) {
210 cl_assert_equal_i(0, error);
211 cl_assert_equal_i(expected_value, current_value);
212 } else {
213 cl_assert_equal_i(expected_value, error);
214 }
215 }
216
217 static void assert_config_entry_on_init(
218 const char *config_key, int expected_value)
219 {
220 assert_config_entry_on_init_bytype(config_key, expected_value, true);
221 git_repository_free(g_repo);
222 g_repo = NULL;
223
224 assert_config_entry_on_init_bytype(config_key, expected_value, false);
225 }
226
227 void test_repo_init__detect_filemode(void)
228 {
229 assert_config_entry_on_init("core.filemode", cl_is_chmod_supported());
230 }
231
232 void test_repo_init__detect_ignorecase(void)
233 {
234 struct stat st;
235 bool found_without_match;
236
237 cl_git_write2file("testCAPS", "whatever\n", 0, O_CREAT | O_WRONLY, 0666);
238 found_without_match = (p_stat("Testcaps", &st) == 0);
239 cl_must_pass(p_unlink("testCAPS"));
240
241 assert_config_entry_on_init(
242 "core.ignorecase", found_without_match ? true : GIT_ENOTFOUND);
243 }
244
245 /*
246 * Windows: if the filesystem supports symlinks (because we're running
247 * as administrator, or because the user has opted into it for normal
248 * users) then we can also opt-in explicitly by settings `core.symlinks`
249 * in the global config. Symlinks remain off by default.
250 */
251
252 void test_repo_init__symlinks_win32_enabled_by_global_config(void)
253 {
254 #ifndef GIT_WIN32
255 cl_skip();
256 #else
257 git_config *config, *repo_config;
258 int val;
259
260 if (!git_fs_path_supports_symlinks("link"))
261 cl_skip();
262
263 create_tmp_global_config("tmp_global_config", "core.symlinks", "true");
264
265 /*
266 * Create a new repository (can't use `assert_config_on_init` since we
267 * want to examine configuration levels with more granularity.)
268 */
269 cl_git_pass(git_repository_init(&g_repo, "config_entry/test.non.bare.git", false));
270
271 /* Ensure that core.symlinks remains set (via the global config). */
272 cl_git_pass(git_repository_config(&config, g_repo));
273 cl_git_pass(git_config_get_bool(&val, config, "core.symlinks"));
274 cl_assert_equal_i(1, val);
275
276 /*
277 * Ensure that the repository config does not set core.symlinks.
278 * It should remain inherited.
279 */
280 cl_git_pass(git_config_open_level(&repo_config, config, GIT_CONFIG_LEVEL_LOCAL));
281 cl_git_fail_with(GIT_ENOTFOUND, git_config_get_bool(&val, repo_config, "core.symlinks"));
282 git_config_free(repo_config);
283
284 git_config_free(config);
285
286 git_repository_free(g_repo);
287 g_repo = NULL;
288 #endif
289 }
290
291 void test_repo_init__symlinks_win32_off_by_default(void)
292 {
293 #ifndef GIT_WIN32
294 cl_skip();
295 #else
296 assert_config_entry_on_init("core.symlinks", false);
297 #endif
298 }
299
300 void test_repo_init__symlinks_posix_detected(void)
301 {
302 #ifdef GIT_WIN32
303 cl_skip();
304 #else
305 assert_config_entry_on_init(
306 "core.symlinks", git_fs_path_supports_symlinks("link") ? GIT_ENOTFOUND : false);
307 #endif
308 }
309
310 void test_repo_init__detect_precompose_unicode_required(void)
311 {
312 #ifdef GIT_USE_ICONV
313 char *composed = "ḱṷṓn", *decomposed = "ḱṷṓn";
314 struct stat st;
315 bool found_with_nfd;
316
317 cl_git_write2file(composed, "whatever\n", 0, O_CREAT | O_WRONLY, 0666);
318 found_with_nfd = (p_stat(decomposed, &st) == 0);
319 cl_must_pass(p_unlink(composed));
320
321 assert_config_entry_on_init("core.precomposeunicode", found_with_nfd);
322 #else
323 assert_config_entry_on_init("core.precomposeunicode", GIT_ENOTFOUND);
324 #endif
325 }
326
327 void test_repo_init__reinit_doesnot_overwrite_ignorecase(void)
328 {
329 git_config *config;
330 int current_value;
331
332 /* Init a new repo */
333 cl_set_cleanup(&cleanup_repository, "not.overwrite.git");
334 cl_git_pass(git_repository_init(&g_repo, "not.overwrite.git", 1));
335
336 /* Change the "core.ignorecase" config value to something unlikely */
337 git_repository_config(&config, g_repo);
338 git_config_set_int32(config, "core.ignorecase", 42);
339 git_config_free(config);
340 git_repository_free(g_repo);
341 g_repo = NULL;
342
343 /* Reinit the repository */
344 cl_git_pass(git_repository_init(&g_repo, "not.overwrite.git", 1));
345 git_repository_config(&config, g_repo);
346
347 /* Ensure the "core.ignorecase" config value hasn't been updated */
348 cl_git_pass(git_config_get_int32(&current_value, config, "core.ignorecase"));
349 cl_assert_equal_i(42, current_value);
350
351 git_config_free(config);
352 }
353
354 void test_repo_init__reinit_overwrites_filemode(void)
355 {
356 int expected = cl_is_chmod_supported(), current_value;
357
358 /* Init a new repo */
359 cl_set_cleanup(&cleanup_repository, "overwrite.git");
360 cl_git_pass(git_repository_init(&g_repo, "overwrite.git", 1));
361
362 /* Change the "core.filemode" config value to something unlikely */
363 cl_repo_set_bool(g_repo, "core.filemode", !expected);
364
365 git_repository_free(g_repo);
366 g_repo = NULL;
367
368 /* Reinit the repository */
369 cl_git_pass(git_repository_init(&g_repo, "overwrite.git", 1));
370
371 /* Ensure the "core.filemode" config value has been reset */
372 current_value = cl_repo_get_bool(g_repo, "core.filemode");
373 cl_assert_equal_i(expected, current_value);
374 }
375
376 void test_repo_init__sets_logAllRefUpdates_according_to_type_of_repository(void)
377 {
378 assert_config_entry_on_init_bytype("core.logallrefupdates", GIT_ENOTFOUND, true);
379 git_repository_free(g_repo);
380 assert_config_entry_on_init_bytype("core.logallrefupdates", true, false);
381 }
382
383 void test_repo_init__extended_0(void)
384 {
385 git_repository_init_options opts = GIT_REPOSITORY_INIT_OPTIONS_INIT;
386
387 /* without MKDIR this should fail */
388 cl_git_fail(git_repository_init_ext(&g_repo, "extended", &opts));
389
390 /* make the directory first, then it should succeed */
391 cl_git_pass(git_futils_mkdir("extended", 0775, 0));
392 cl_git_pass(git_repository_init_ext(&g_repo, "extended", &opts));
393
394 cl_assert(!git__suffixcmp(git_repository_workdir(g_repo), "/extended/"));
395 cl_assert(!git__suffixcmp(git_repository_path(g_repo), "/extended/.git/"));
396 cl_assert(!git_repository_is_bare(g_repo));
397 cl_assert(git_repository_is_empty(g_repo));
398
399 cleanup_repository("extended");
400 }
401
402 void test_repo_init__extended_1(void)
403 {
404 git_reference *ref;
405 git_remote *remote;
406 struct stat st;
407 git_repository_init_options opts = GIT_REPOSITORY_INIT_OPTIONS_INIT;
408
409 opts.flags = GIT_REPOSITORY_INIT_MKPATH |
410 GIT_REPOSITORY_INIT_NO_DOTGIT_DIR;
411 opts.mode = GIT_REPOSITORY_INIT_SHARED_GROUP;
412 opts.workdir_path = "../c_wd";
413 opts.description = "Awesomest test repository evah";
414 opts.initial_head = "development";
415 opts.origin_url = "https://github.com/libgit2/libgit2.git";
416
417 cl_git_pass(git_repository_init_ext(&g_repo, "root/b/c.git", &opts));
418
419 cl_assert(!git__suffixcmp(git_repository_workdir(g_repo), "/c_wd/"));
420 cl_assert(!git__suffixcmp(git_repository_path(g_repo), "/c.git/"));
421 cl_assert(git_fs_path_isfile("root/b/c_wd/.git"));
422 cl_assert(!git_repository_is_bare(g_repo));
423 /* repo will not be counted as empty because we set head to "development" */
424 cl_assert(!git_repository_is_empty(g_repo));
425
426 cl_git_pass(git_fs_path_lstat(git_repository_path(g_repo), &st));
427 cl_assert(S_ISDIR(st.st_mode));
428 if (cl_is_chmod_supported())
429 cl_assert((S_ISGID & st.st_mode) == S_ISGID);
430 else
431 cl_assert((S_ISGID & st.st_mode) == 0);
432
433 cl_git_pass(git_reference_lookup(&ref, g_repo, "HEAD"));
434 cl_assert(git_reference_type(ref) == GIT_REFERENCE_SYMBOLIC);
435 cl_assert_equal_s("refs/heads/development", git_reference_symbolic_target(ref));
436 git_reference_free(ref);
437
438 cl_git_pass(git_remote_lookup(&remote, g_repo, "origin"));
439 cl_assert_equal_s("origin", git_remote_name(remote));
440 cl_assert_equal_s(opts.origin_url, git_remote_url(remote));
441 git_remote_free(remote);
442
443 git_repository_free(g_repo);
444 cl_fixture_cleanup("root");
445 }
446
447 void test_repo_init__relative_gitdir(void)
448 {
449 git_repository_init_options opts = GIT_REPOSITORY_INIT_OPTIONS_INIT;
450 git_str dot_git_content = GIT_STR_INIT;
451
452 opts.workdir_path = "../c_wd";
453 opts.flags =
454 GIT_REPOSITORY_INIT_MKPATH |
455 GIT_REPOSITORY_INIT_RELATIVE_GITLINK |
456 GIT_REPOSITORY_INIT_NO_DOTGIT_DIR;
457
458 /* make the directory first, then it should succeed */
459 cl_git_pass(git_repository_init_ext(&g_repo, "root/b/my_repository", &opts));
460
461 cl_assert(!git__suffixcmp(git_repository_workdir(g_repo), "root/b/c_wd/"));
462 cl_assert(!git__suffixcmp(git_repository_path(g_repo), "root/b/my_repository/"));
463 cl_assert(!git_repository_is_bare(g_repo));
464 cl_assert(git_repository_is_empty(g_repo));
465
466 /* Verify that the gitlink and worktree entries are relative */
467
468 /* Verify worktree */
469 assert_config_entry_value(g_repo, "core.worktree", "../c_wd/");
470
471 /* Verify gitlink */
472 cl_git_pass(git_futils_readbuffer(&dot_git_content, "root/b/c_wd/.git"));
473 cl_assert_equal_s("gitdir: ../my_repository/", dot_git_content.ptr);
474
475 git_str_dispose(&dot_git_content);
476 cleanup_repository("root");
477 }
478
479 void test_repo_init__relative_gitdir_2(void)
480 {
481 git_repository_init_options opts = GIT_REPOSITORY_INIT_OPTIONS_INIT;
482 git_str dot_git_content = GIT_STR_INIT;
483 git_str full_path = GIT_STR_INIT;
484
485 cl_git_pass(git_fs_path_prettify(&full_path, ".", NULL));
486 cl_git_pass(git_str_joinpath(&full_path, full_path.ptr, "root/b/c_wd"));
487
488 opts.workdir_path = full_path.ptr;
489 opts.flags =
490 GIT_REPOSITORY_INIT_MKPATH |
491 GIT_REPOSITORY_INIT_RELATIVE_GITLINK |
492 GIT_REPOSITORY_INIT_NO_DOTGIT_DIR;
493
494 /* make the directory first, then it should succeed */
495 cl_git_pass(git_repository_init_ext(&g_repo, "root/b/my_repository", &opts));
496 git_str_dispose(&full_path);
497
498 cl_assert(!git__suffixcmp(git_repository_workdir(g_repo), "root/b/c_wd/"));
499 cl_assert(!git__suffixcmp(git_repository_path(g_repo), "root/b/my_repository/"));
500 cl_assert(!git_repository_is_bare(g_repo));
501 cl_assert(git_repository_is_empty(g_repo));
502
503 /* Verify that the gitlink and worktree entries are relative */
504
505 /* Verify worktree */
506 assert_config_entry_value(g_repo, "core.worktree", "../c_wd/");
507
508 /* Verify gitlink */
509 cl_git_pass(git_futils_readbuffer(&dot_git_content, "root/b/c_wd/.git"));
510 cl_assert_equal_s("gitdir: ../my_repository/", dot_git_content.ptr);
511
512 git_str_dispose(&dot_git_content);
513 cleanup_repository("root");
514 }
515
516 void test_repo_init__can_reinit_an_initialized_repository(void)
517 {
518 git_repository *reinit;
519
520 cl_set_cleanup(&cleanup_repository, "extended");
521
522 cl_git_pass(git_futils_mkdir("extended", 0775, 0));
523 cl_git_pass(git_repository_init(&g_repo, "extended", false));
524
525 cl_git_pass(git_repository_init(&reinit, "extended", false));
526
527 cl_assert_equal_s(git_repository_path(g_repo), git_repository_path(reinit));
528
529 git_repository_free(reinit);
530 }
531
532 void test_repo_init__init_with_initial_commit(void)
533 {
534 git_index *index;
535
536 cl_set_cleanup(&cleanup_repository, "committed");
537
538 /* Initialize the repository */
539 cl_git_pass(git_repository_init(&g_repo, "committed", 0));
540
541 /* Index will be automatically created when requested for a new repo */
542 cl_git_pass(git_repository_index(&index, g_repo));
543
544 /* Create a file so we can commit it
545 *
546 * If you are writing code outside the test suite, you can create this
547 * file any way that you like, such as:
548 * FILE *fp = fopen("committed/file.txt", "w");
549 * fputs("some stuff\n", fp);
550 * fclose(fp);
551 * We like to use the help functions because they do error detection
552 * in a way that's easily compatible with our test suite.
553 */
554 cl_git_mkfile("committed/file.txt", "some stuff\n");
555
556 /* Add file to the index */
557 cl_git_pass(git_index_add_bypath(index, "file.txt"));
558 cl_git_pass(git_index_write(index));
559
560 /* Intentionally not using cl_repo_commit_from_index here so this code
561 * can be used as an example of how an initial commit is typically
562 * made to a repository...
563 */
564
565 /* Make sure we're ready to use git_signature_default :-) */
566 {
567 git_config *cfg, *local;
568 cl_git_pass(git_repository_config(&cfg, g_repo));
569 cl_git_pass(git_config_open_level(&local, cfg, GIT_CONFIG_LEVEL_LOCAL));
570 cl_git_pass(git_config_set_string(local, "user.name", "Test User"));
571 cl_git_pass(git_config_set_string(local, "user.email", "t@example.com"));
572 git_config_free(local);
573 git_config_free(cfg);
574 }
575
576 /* Create a commit with the new contents of the index */
577 {
578 git_signature *sig;
579 git_oid tree_id, commit_id;
580 git_tree *tree;
581
582 cl_git_pass(git_signature_default(&sig, g_repo));
583 cl_git_pass(git_index_write_tree(&tree_id, index));
584 cl_git_pass(git_tree_lookup(&tree, g_repo, &tree_id));
585
586 cl_git_pass(git_commit_create_v(
587 &commit_id, g_repo, "HEAD", sig, sig,
588 NULL, "First", tree, 0));
589
590 git_tree_free(tree);
591 git_signature_free(sig);
592 }
593
594 git_index_free(index);
595 }
596
597 void test_repo_init__at_filesystem_root(void)
598 {
599 git_repository *repo;
600 const char *sandbox = clar_sandbox_path();
601 git_str root = GIT_STR_INIT;
602 int root_len;
603
604 if (!cl_is_env_set("GITTEST_INVASIVE_FS_STRUCTURE"))
605 cl_skip();
606
607 root_len = git_fs_path_root(sandbox);
608 cl_assert(root_len >= 0);
609
610 git_str_put(&root, sandbox, root_len+1);
611 git_str_joinpath(&root, root.ptr, "libgit2_test_dir");
612
613 cl_assert(!git_fs_path_exists(root.ptr));
614
615 cl_git_pass(git_repository_init(&repo, root.ptr, 0));
616 cl_assert(git_fs_path_isdir(root.ptr));
617 cl_git_pass(git_futils_rmdir_r(root.ptr, NULL, GIT_RMDIR_REMOVE_FILES));
618
619 git_str_dispose(&root);
620 git_repository_free(repo);
621 }
622
623 void test_repo_init__nonexisting_directory(void)
624 {
625 git_repository_init_options opts = GIT_REPOSITORY_INIT_OPTIONS_INIT;
626 git_repository *repo;
627
628 /*
629 * If creating a repo with non-existing parent directories, then libgit2
630 * will by default create the complete directory hierarchy if using
631 * `git_repository_init`. Thus, let's use the extended version and not
632 * set the `GIT_REPOSITORY_INIT_MKPATH` flag.
633 */
634 cl_git_fail(git_repository_init_ext(&repo, "nonexisting/path", &opts));
635 }
636
637 void test_repo_init__nonexisting_root(void)
638 {
639 #ifdef GIT_WIN32
640 git_repository *repo;
641
642 /*
643 * This really only depends on the nonexistence of the Q: drive. We
644 * cannot implement the equivalent test on Unix systems, as there is
645 * fundamentally no path that is disconnected from the root directory.
646 */
647 cl_git_fail(git_repository_init(&repo, "Q:/non/existent/path", 0));
648 cl_git_fail(git_repository_init(&repo, "Q:\\non\\existent\\path", 0));
649 #else
650 clar__skip();
651 #endif
652 }
653
654 void test_repo_init__unwriteable_directory(void)
655 {
656 #ifndef GIT_WIN32
657 git_repository *repo;
658
659 if (geteuid() == 0)
660 clar__skip();
661
662 /*
663 * Create a non-writeable directory so that we cannot create directories
664 * inside of it. The root user has CAP_DAC_OVERRIDE, so he doesn't care
665 * for the directory permissions and thus we need to skip the test if
666 * run as root user.
667 */
668 cl_must_pass(p_mkdir("unwriteable", 0444));
669 cl_git_fail(git_repository_init(&repo, "unwriteable/repo", 0));
670 cl_must_pass(p_rmdir("unwriteable"));
671 #else
672 clar__skip();
673 #endif
674 }
675
676 void test_repo_init__defaultbranch_config(void)
677 {
678 git_reference *head;
679
680 cl_set_cleanup(&cleanup_repository, "repo");
681
682 create_tmp_global_config("tmp_global_path", "init.defaultbranch", "my_default_branch");
683
684 cl_git_pass(git_repository_init(&g_repo, "repo", 0));
685 cl_git_pass(git_reference_lookup(&head, g_repo, "HEAD"));
686
687 cl_assert_equal_s("refs/heads/my_default_branch", git_reference_symbolic_target(head));
688
689 git_reference_free(head);
690 }
691
692 void test_repo_init__defaultbranch_config_empty(void)
693 {
694 git_reference *head;
695
696 cl_set_cleanup(&cleanup_repository, "repo");
697
698 create_tmp_global_config("tmp_global_path", "init.defaultbranch", "");
699
700 cl_git_pass(git_repository_init(&g_repo, "repo", 0));
701 cl_git_pass(git_reference_lookup(&head, g_repo, "HEAD"));
702
703 cl_assert_equal_s("refs/heads/master", git_reference_symbolic_target(head));
704
705 git_reference_free(head);
706 }
707
708 void test_repo_init__longpath(void)
709 {
710 #ifdef GIT_WIN32
711 size_t padding = CONST_STRLEN("objects/pack/pack-.pack.lock") + GIT_OID_HEXSZ;
712 size_t max, i;
713 git_str path = GIT_STR_INIT;
714 git_repository *one = NULL, *two = NULL;
715
716 /*
717 * Files within repositories need to fit within MAX_PATH;
718 * that means a repo path must be at most (MAX_PATH - 18).
719 */
720 cl_git_pass(git_str_puts(&path, clar_sandbox_path()));
721 cl_git_pass(git_str_putc(&path, '/'));
722
723 max = ((MAX_PATH) - path.size) - padding;
724
725 for (i = 0; i < max - 1; i++)
726 cl_git_pass(git_str_putc(&path, 'a'));
727
728 cl_git_pass(git_repository_init(&one, path.ptr, 1));
729
730 /* Paths longer than this are rejected */
731 cl_git_pass(git_str_putc(&path, 'z'));
732 cl_git_fail(git_repository_init(&two, path.ptr, 1));
733
734 git_repository_free(one);
735 git_repository_free(two);
736 git_str_dispose(&path);
737 #endif
738 }