diff options
author | Edward Thomson <ethomson@edwardthomson.com> | 2019-07-20 11:02:30 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-07-20 11:02:30 +0100 |
commit | 964c1c60011322a16a593f034a8466614f183742 (patch) | |
tree | 2bed73f99c71e06c3b8e6d2ae9a4792b3cf426bb | |
parent | 3424c21057441e9d592d1edfb5744c56cc29a30b (diff) | |
parent | 9d46f1675989c20663de80c003256bc586496771 (diff) | |
download | libgit2-964c1c60011322a16a593f034a8466614f183742.tar.gz |
Merge pull request #5176 from pks-t/pks/repo-template-head
repository: do not initialize HEAD if it's provided by templates
-rw-r--r-- | src/repository.c | 72 | ||||
-rw-r--r-- | tests/repo/init.c | 269 | ||||
-rw-r--r-- | tests/repo/template.c | 295 |
3 files changed, 335 insertions, 301 deletions
diff --git a/src/repository.c b/src/repository.c index d8eb4ba07..002e84f91 100644 --- a/src/repository.c +++ b/src/repository.c @@ -1360,10 +1360,11 @@ int git_repository_create_head(const char *git_dir, const char *ref_name) git_buf ref_path = GIT_BUF_INIT; git_filebuf ref = GIT_FILEBUF_INIT; const char *fmt; + int error; - if (git_buf_joinpath(&ref_path, git_dir, GIT_HEAD_FILE) < 0 || - git_filebuf_open(&ref, ref_path.ptr, 0, GIT_REFS_FILE_MODE) < 0) - goto fail; + if ((error = git_buf_joinpath(&ref_path, git_dir, GIT_HEAD_FILE)) < 0 || + (error = git_filebuf_open(&ref, ref_path.ptr, 0, GIT_REFS_FILE_MODE)) < 0) + goto out; if (!ref_name) ref_name = GIT_BRANCH_MASTER; @@ -1373,17 +1374,14 @@ int git_repository_create_head(const char *git_dir, const char *ref_name) else fmt = "ref: " GIT_REFS_HEADS_DIR "%s\n"; - if (git_filebuf_printf(&ref, fmt, ref_name) < 0 || - git_filebuf_commit(&ref) < 0) - goto fail; - - git_buf_dispose(&ref_path); - return 0; + if ((error = git_filebuf_printf(&ref, fmt, ref_name)) < 0 || + (error = git_filebuf_commit(&ref)) < 0) + goto out; -fail: +out: git_buf_dispose(&ref_path); git_filebuf_cleanup(&ref); - return -1; + return error; } static bool is_chmod_supported(const char *file_path) @@ -2058,53 +2056,59 @@ int git_repository_init_ext( const char *given_repo, git_repository_init_options *opts) { - int error; git_buf repo_path = GIT_BUF_INIT, wd_path = GIT_BUF_INIT, - common_path = GIT_BUF_INIT; + common_path = GIT_BUF_INIT, head_path = GIT_BUF_INIT; const char *wd; + int error; assert(out && given_repo && opts); GIT_ERROR_CHECK_VERSION(opts, GIT_REPOSITORY_INIT_OPTIONS_VERSION, "git_repository_init_options"); - error = repo_init_directories(&repo_path, &wd_path, given_repo, opts); - if (error < 0) - goto cleanup; + if ((error = repo_init_directories(&repo_path, &wd_path, given_repo, opts)) < 0) + goto out; wd = (opts->flags & GIT_REPOSITORY_INIT_BARE) ? NULL : git_buf_cstr(&wd_path); - if (valid_repository_path(&repo_path, &common_path)) { + if (valid_repository_path(&repo_path, &common_path)) { if ((opts->flags & GIT_REPOSITORY_INIT_NO_REINIT) != 0) { git_error_set(GIT_ERROR_REPOSITORY, "attempt to reinitialize '%s'", given_repo); error = GIT_EEXISTS; - goto cleanup; + goto out; } opts->flags |= GIT_REPOSITORY_INIT__IS_REINIT; - error = repo_init_config( - repo_path.ptr, wd, opts->flags, opts->mode); + if ((error = repo_init_config(repo_path.ptr, wd, opts->flags, opts->mode)) < 0) + goto out; /* TODO: reinitialize the templates */ + } else { + if ((error = repo_init_structure(repo_path.ptr, wd, opts)) < 0 || + (error = repo_init_config(repo_path.ptr, wd, opts->flags, opts->mode)) < 0 || + (error = git_buf_joinpath(&head_path, repo_path.ptr, GIT_HEAD_FILE)) < 0) + goto out; + + /* + * Only set the new HEAD if the file does not exist already via + * a template or if the caller has explicitly supplied an + * initial HEAD value. + */ + if ((!git_path_exists(head_path.ptr) || opts->initial_head) && + (error = git_repository_create_head(repo_path.ptr, opts->initial_head)) < 0) + goto out; } - else { - if (!(error = repo_init_structure( - repo_path.ptr, wd, opts)) && - !(error = repo_init_config( - repo_path.ptr, wd, opts->flags, opts->mode))) - error = git_repository_create_head( - repo_path.ptr, opts->initial_head); - } - if (error < 0) - goto cleanup; - error = git_repository_open(out, repo_path.ptr); + if ((error = git_repository_open(out, repo_path.ptr)) < 0) + goto out; - if (!error && opts->origin_url) - error = repo_init_create_origin(*out, opts->origin_url); + if (opts->origin_url && + (error = repo_init_create_origin(*out, opts->origin_url)) < 0) + goto out; -cleanup: +out: + git_buf_dispose(&head_path); git_buf_dispose(&common_path); git_buf_dispose(&repo_path); git_buf_dispose(&wd_path); diff --git a/tests/repo/init.c b/tests/repo/init.c index f2155b4cd..9879ef1f7 100644 --- a/tests/repo/init.c +++ b/tests/repo/init.c @@ -13,20 +13,13 @@ enum repo_mode { static git_repository *_repo = NULL; static git_buf _global_path = GIT_BUF_INIT; -static mode_t g_umask = 0; void test_repo_init__initialize(void) { _repo = NULL; - /* load umask if not already loaded */ - if (!g_umask) { - g_umask = p_umask(022); - (void)p_umask(g_umask); - } - - git_libgit2_opts(GIT_OPT_GET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, - &_global_path); + git_libgit2_opts(GIT_OPT_GET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, + &_global_path); } void test_repo_init__cleanup(void) @@ -380,17 +373,6 @@ void test_repo_init__sets_logAllRefUpdates_according_to_type_of_repository(void) assert_config_entry_on_init_bytype("core.logallrefupdates", true, false); } -void test_repo_init__empty_template_path(void) -{ - git_repository_init_options opts = GIT_REPOSITORY_INIT_OPTIONS_INIT; - opts.template_path = ""; - - cl_git_pass(git_futils_mkdir("foo", 0755, 0)); - cl_git_pass(git_repository_init_ext(&_repo, "foo", &opts)); - - cleanup_repository("foo"); -} - void test_repo_init__extended_0(void) { git_repository_init_options opts = GIT_REPOSITORY_INIT_OPTIONS_INIT; @@ -524,253 +506,6 @@ void test_repo_init__relative_gitdir_2(void) cleanup_repository("root"); } -#define CLEAR_FOR_CORE_FILEMODE(M) ((M) &= ~0177) - -static void assert_hooks_match( - const char *template_dir, - const char *repo_dir, - const char *hook_path, - bool core_filemode) -{ - git_buf expected = GIT_BUF_INIT; - git_buf actual = GIT_BUF_INIT; - struct stat expected_st, st; - - cl_git_pass(git_buf_joinpath(&expected, template_dir, hook_path)); - cl_git_pass(git_path_lstat(expected.ptr, &expected_st)); - - cl_git_pass(git_buf_joinpath(&actual, repo_dir, hook_path)); - cl_git_pass(git_path_lstat(actual.ptr, &st)); - - cl_assert(expected_st.st_size == st.st_size); - - if (GIT_MODE_TYPE(expected_st.st_mode) != GIT_FILEMODE_LINK) { - mode_t expected_mode = - GIT_MODE_TYPE(expected_st.st_mode) | - (GIT_PERMS_FOR_WRITE(expected_st.st_mode) & ~g_umask); - - if (!core_filemode) { - CLEAR_FOR_CORE_FILEMODE(expected_mode); - CLEAR_FOR_CORE_FILEMODE(st.st_mode); - } - - cl_assert_equal_i_fmt(expected_mode, st.st_mode, "%07o"); - } - - git_buf_dispose(&expected); - git_buf_dispose(&actual); -} - -static void assert_mode_seems_okay( - const char *base, const char *path, - git_filemode_t expect_mode, bool expect_setgid, bool core_filemode) -{ - git_buf full = GIT_BUF_INIT; - struct stat st; - - cl_git_pass(git_buf_joinpath(&full, base, path)); - cl_git_pass(git_path_lstat(full.ptr, &st)); - git_buf_dispose(&full); - - if (!core_filemode) { - CLEAR_FOR_CORE_FILEMODE(expect_mode); - CLEAR_FOR_CORE_FILEMODE(st.st_mode); - expect_setgid = false; - } - - if (S_ISGID != 0) - cl_assert_equal_b(expect_setgid, (st.st_mode & S_ISGID) != 0); - - cl_assert_equal_b( - GIT_PERMS_IS_EXEC(expect_mode), GIT_PERMS_IS_EXEC(st.st_mode)); - - cl_assert_equal_i_fmt( - GIT_MODE_TYPE(expect_mode), GIT_MODE_TYPE(st.st_mode), "%07o"); -} - -static const char *template_sandbox(const char *name) -{ - git_buf hooks_path = GIT_BUF_INIT, link_path = GIT_BUF_INIT, - dotfile_path = GIT_BUF_INIT; - const char *path = cl_fixture(name); - - cl_fixture_sandbox(name); - - /* create a symlink from link.sample to update.sample if the filesystem - * supports it. - */ - - cl_git_pass(git_buf_joinpath(&hooks_path, name, "hooks")); - cl_git_pass(git_buf_joinpath(&link_path, hooks_path.ptr, "link.sample")); - -#ifdef GIT_WIN32 - cl_git_mkfile(link_path.ptr, "#!/bin/sh\necho hello, world\n"); -#else - cl_must_pass(symlink("update.sample", link_path.ptr)); -#endif - - /* create a file starting with a dot */ - cl_git_pass(git_buf_joinpath(&dotfile_path, hooks_path.ptr, ".dotfile")); - cl_git_mkfile(dotfile_path.ptr, "something\n"); - git_buf_dispose(&dotfile_path); - - git_buf_dispose(&dotfile_path); - git_buf_dispose(&link_path); - git_buf_dispose(&hooks_path); - - return path; -} - -static void configure_templatedir(const char *template_path) -{ - create_tmp_global_config("tmp_global_path", "init.templatedir", template_path); -} - -static void validate_templates(git_repository *repo, const char *template_path) -{ - git_buf template_description = GIT_BUF_INIT; - git_buf repo_description = GIT_BUF_INIT; - git_buf expected = GIT_BUF_INIT; - git_buf actual = GIT_BUF_INIT; - int filemode; - - cl_git_pass(git_buf_joinpath(&template_description, template_path, - "description")); - cl_git_pass(git_buf_joinpath(&repo_description, git_repository_path(repo), - "description")); - - cl_git_pass(git_futils_readbuffer(&expected, template_description.ptr)); - cl_git_pass(git_futils_readbuffer(&actual, repo_description.ptr)); - - cl_assert_equal_s(expected.ptr, actual.ptr); - - filemode = cl_repo_get_bool(repo, "core.filemode"); - - assert_hooks_match( - template_path, git_repository_path(repo), - "hooks/update.sample", filemode); - - assert_hooks_match( - template_path, git_repository_path(repo), - "hooks/link.sample", filemode); - - assert_hooks_match( - template_path, git_repository_path(repo), - "hooks/.dotfile", filemode); - - git_buf_dispose(&expected); - git_buf_dispose(&actual); - git_buf_dispose(&repo_description); - git_buf_dispose(&template_description); -} - -void test_repo_init__external_templates_specified_in_options(void) -{ - git_repository_init_options opts = GIT_REPOSITORY_INIT_OPTIONS_INIT; - - cl_set_cleanup(&cleanup_repository, "templated.git"); - template_sandbox("template"); - - opts.flags = GIT_REPOSITORY_INIT_MKPATH | GIT_REPOSITORY_INIT_BARE | - GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE; - opts.template_path = "template"; - - cl_git_pass(git_repository_init_ext(&_repo, "templated.git", &opts)); - - cl_assert(git_repository_is_bare(_repo)); - - cl_assert(!git__suffixcmp(git_repository_path(_repo), "/templated.git/")); - - validate_templates(_repo, "template"); - cl_fixture_cleanup("template"); -} - -void test_repo_init__external_templates_specified_in_config(void) -{ - git_buf template_path = GIT_BUF_INIT; - - git_repository_init_options opts = GIT_REPOSITORY_INIT_OPTIONS_INIT; - - cl_set_cleanup(&cleanup_repository, "templated.git"); - template_sandbox("template"); - - cl_git_pass(git_buf_joinpath(&template_path, clar_sandbox_path(), - "template")); - - configure_templatedir(template_path.ptr); - - opts.flags = GIT_REPOSITORY_INIT_MKPATH | GIT_REPOSITORY_INIT_BARE | - GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE; - - cl_git_pass(git_repository_init_ext(&_repo, "templated.git", &opts)); - - validate_templates(_repo, "template"); - cl_fixture_cleanup("template"); - - git_buf_dispose(&template_path); -} - -void test_repo_init__external_templates_with_leading_dot(void) -{ - git_buf template_path = GIT_BUF_INIT; - - git_repository_init_options opts = GIT_REPOSITORY_INIT_OPTIONS_INIT; - - cl_set_cleanup(&cleanup_repository, "templated.git"); - template_sandbox("template"); - - cl_must_pass(p_rename("template", ".template_with_leading_dot")); - - cl_git_pass(git_buf_joinpath(&template_path, clar_sandbox_path(), - ".template_with_leading_dot")); - - configure_templatedir(template_path.ptr); - - opts.flags = GIT_REPOSITORY_INIT_MKPATH | GIT_REPOSITORY_INIT_BARE | - GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE; - - cl_git_pass(git_repository_init_ext(&_repo, "templated.git", &opts)); - - validate_templates(_repo, ".template_with_leading_dot"); - cl_fixture_cleanup(".template_with_leading_dot"); - - git_buf_dispose(&template_path); -} - -void test_repo_init__extended_with_template_and_shared_mode(void) -{ - git_repository_init_options opts = GIT_REPOSITORY_INIT_OPTIONS_INIT; - int filemode = true; - const char *repo_path = NULL; - - cl_set_cleanup(&cleanup_repository, "init_shared_from_tpl"); - template_sandbox("template"); - - opts.flags = GIT_REPOSITORY_INIT_MKPATH | - GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE; - opts.template_path = "template"; - opts.mode = GIT_REPOSITORY_INIT_SHARED_GROUP; - - cl_git_pass(git_repository_init_ext(&_repo, "init_shared_from_tpl", &opts)); - - cl_assert(!git_repository_is_bare(_repo)); - cl_assert(!git__suffixcmp(git_repository_path(_repo), "/init_shared_from_tpl/.git/")); - - filemode = cl_repo_get_bool(_repo, "core.filemode"); - - repo_path = git_repository_path(_repo); - assert_mode_seems_okay(repo_path, "hooks", - GIT_FILEMODE_TREE | GIT_REPOSITORY_INIT_SHARED_GROUP, true, filemode); - assert_mode_seems_okay(repo_path, "info", - GIT_FILEMODE_TREE | GIT_REPOSITORY_INIT_SHARED_GROUP, true, filemode); - assert_mode_seems_okay(repo_path, "description", - GIT_FILEMODE_BLOB, false, filemode); - - validate_templates(_repo, "template"); - - cl_fixture_cleanup("template"); -} - void test_repo_init__can_reinit_an_initialized_repository(void) { git_repository *reinit; diff --git a/tests/repo/template.c b/tests/repo/template.c new file mode 100644 index 000000000..7ccd93521 --- /dev/null +++ b/tests/repo/template.c @@ -0,0 +1,295 @@ +#include "clar_libgit2.h" + +#include "fileops.h" +#include "repo/repo_helpers.h" + +#define CLEAR_FOR_CORE_FILEMODE(M) ((M) &= ~0177) + +static git_repository *_repo = NULL; +static mode_t g_umask = 0; +static git_buf _global_path = GIT_BUF_INIT; + +static const char *fixture_repo; +static const char *fixture_templates; + +void test_repo_template__initialize(void) +{ + _repo = NULL; + + /* load umask if not already loaded */ + if (!g_umask) { + g_umask = p_umask(022); + (void)p_umask(g_umask); + } +} + +void test_repo_template__cleanup(void) +{ + git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, + _global_path.ptr); + git_buf_dispose(&_global_path); + + cl_fixture_cleanup("tmp_global_path"); + + if (fixture_repo) { + cl_fixture_cleanup(fixture_repo); + fixture_repo = NULL; + } + + if (fixture_templates) { + cl_fixture_cleanup(fixture_templates); + fixture_templates = NULL; + } + + git_repository_free(_repo); + _repo = NULL; +} + +static void assert_hooks_match( + const char *template_dir, + const char *repo_dir, + const char *hook_path, + bool core_filemode) +{ + git_buf expected = GIT_BUF_INIT; + git_buf actual = GIT_BUF_INIT; + struct stat expected_st, st; + + cl_git_pass(git_buf_joinpath(&expected, template_dir, hook_path)); + cl_git_pass(git_path_lstat(expected.ptr, &expected_st)); + + cl_git_pass(git_buf_joinpath(&actual, repo_dir, hook_path)); + cl_git_pass(git_path_lstat(actual.ptr, &st)); + + cl_assert(expected_st.st_size == st.st_size); + + if (GIT_MODE_TYPE(expected_st.st_mode) != GIT_FILEMODE_LINK) { + mode_t expected_mode = + GIT_MODE_TYPE(expected_st.st_mode) | + (GIT_PERMS_FOR_WRITE(expected_st.st_mode) & ~g_umask); + + if (!core_filemode) { + CLEAR_FOR_CORE_FILEMODE(expected_mode); + CLEAR_FOR_CORE_FILEMODE(st.st_mode); + } + + cl_assert_equal_i_fmt(expected_mode, st.st_mode, "%07o"); + } + + git_buf_dispose(&expected); + git_buf_dispose(&actual); +} + +static void assert_mode_seems_okay( + const char *base, const char *path, + git_filemode_t expect_mode, bool expect_setgid, bool core_filemode) +{ + git_buf full = GIT_BUF_INIT; + struct stat st; + + cl_git_pass(git_buf_joinpath(&full, base, path)); + cl_git_pass(git_path_lstat(full.ptr, &st)); + git_buf_dispose(&full); + + if (!core_filemode) { + CLEAR_FOR_CORE_FILEMODE(expect_mode); + CLEAR_FOR_CORE_FILEMODE(st.st_mode); + expect_setgid = false; + } + + if (S_ISGID != 0) + cl_assert_equal_b(expect_setgid, (st.st_mode & S_ISGID) != 0); + + cl_assert_equal_b( + GIT_PERMS_IS_EXEC(expect_mode), GIT_PERMS_IS_EXEC(st.st_mode)); + + cl_assert_equal_i_fmt( + GIT_MODE_TYPE(expect_mode), GIT_MODE_TYPE(st.st_mode), "%07o"); +} + +static void setup_repo(const char *name, git_repository_init_options *opts) +{ + cl_git_pass(git_repository_init_ext(&_repo, name, opts)); + fixture_repo = name; +} + +static void setup_templates(const char *name, bool setup_globally) +{ + git_buf path = GIT_BUF_INIT; + + cl_fixture_sandbox("template"); + if (strcmp(name, "template")) + cl_must_pass(p_rename("template", name)); + + fixture_templates = name; + + /* + * Create a symlink from link.sample to update.sample if the filesystem + * supports it. + */ + cl_git_pass(git_buf_join3(&path, '/', name, "hooks", "link.sample")); +#ifdef GIT_WIN32 + cl_git_mkfile(path.ptr, "#!/bin/sh\necho hello, world\n"); +#else + cl_must_pass(p_symlink("update.sample", path.ptr)); +#endif + + git_buf_clear(&path); + + /* Create a file starting with a dot */ + cl_git_pass(git_buf_join3(&path, '/', name, "hooks", ".dotfile")); + cl_git_mkfile(path.ptr, "something\n"); + + git_buf_clear(&path); + + if (setup_globally) { + cl_git_pass(git_buf_joinpath(&path, clar_sandbox_path(), name)); + create_tmp_global_config("tmp_global_path", "init.templatedir", path.ptr); + } + + git_buf_dispose(&path); +} + +static void validate_templates(git_repository *repo, const char *template_path) +{ + git_buf path = GIT_BUF_INIT, expected = GIT_BUF_INIT, actual = GIT_BUF_INIT; + int filemode; + + cl_git_pass(git_buf_joinpath(&path, template_path, "description")); + cl_git_pass(git_futils_readbuffer(&expected, path.ptr)); + + git_buf_clear(&path); + + cl_git_pass(git_buf_joinpath(&path, git_repository_path(repo), "description")); + cl_git_pass(git_futils_readbuffer(&actual, path.ptr)); + + cl_assert_equal_s(expected.ptr, actual.ptr); + + filemode = cl_repo_get_bool(repo, "core.filemode"); + + assert_hooks_match( + template_path, git_repository_path(repo), + "hooks/update.sample", filemode); + assert_hooks_match( + template_path, git_repository_path(repo), + "hooks/link.sample", filemode); + assert_hooks_match( + template_path, git_repository_path(repo), + "hooks/.dotfile", filemode); + + git_buf_dispose(&expected); + git_buf_dispose(&actual); + git_buf_dispose(&path); +} + +void test_repo_template__external_templates_specified_in_options(void) +{ + git_repository_init_options opts = GIT_REPOSITORY_INIT_OPTIONS_INIT; + + opts.flags = GIT_REPOSITORY_INIT_MKPATH | GIT_REPOSITORY_INIT_BARE | + GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE; + opts.template_path = "template"; + + setup_templates("template", false); + setup_repo("templated.git", &opts); + + validate_templates(_repo, "template"); +} + +void test_repo_template__external_templates_specified_in_config(void) +{ + git_repository_init_options opts = GIT_REPOSITORY_INIT_OPTIONS_INIT; + + opts.flags = GIT_REPOSITORY_INIT_MKPATH | GIT_REPOSITORY_INIT_BARE | + GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE; + + setup_templates("template", true); + setup_repo("templated.git", &opts); + + validate_templates(_repo, "template"); +} + +void test_repo_template__external_templates_with_leading_dot(void) +{ + git_repository_init_options opts = GIT_REPOSITORY_INIT_OPTIONS_INIT; + + opts.flags = GIT_REPOSITORY_INIT_MKPATH | GIT_REPOSITORY_INIT_BARE | + GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE; + + setup_templates(".template_with_leading_dot", true); + setup_repo("templated.git", &opts); + + validate_templates(_repo, ".template_with_leading_dot"); +} + +void test_repo_template__extended_with_template_and_shared_mode(void) +{ + git_repository_init_options opts = GIT_REPOSITORY_INIT_OPTIONS_INIT; + const char *repo_path; + int filemode; + + opts.flags = GIT_REPOSITORY_INIT_MKPATH | + GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE; + opts.template_path = "template"; + opts.mode = GIT_REPOSITORY_INIT_SHARED_GROUP; + + setup_templates("template", false); + setup_repo("init_shared_from_tpl", &opts); + + filemode = cl_repo_get_bool(_repo, "core.filemode"); + + repo_path = git_repository_path(_repo); + assert_mode_seems_okay(repo_path, "hooks", + GIT_FILEMODE_TREE | GIT_REPOSITORY_INIT_SHARED_GROUP, true, filemode); + assert_mode_seems_okay(repo_path, "info", + GIT_FILEMODE_TREE | GIT_REPOSITORY_INIT_SHARED_GROUP, true, filemode); + assert_mode_seems_okay(repo_path, "description", + GIT_FILEMODE_BLOB, false, filemode); + + validate_templates(_repo, "template"); +} + +void test_repo_template__templated_head_is_used(void) +{ + git_repository_init_options opts = GIT_REPOSITORY_INIT_OPTIONS_INIT; + git_buf head = GIT_BUF_INIT; + + opts.flags = GIT_REPOSITORY_INIT_MKPATH | GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE; + + setup_templates("template", true); + cl_git_mkfile("template/HEAD", "foobar\n"); + setup_repo("repo", &opts); + + cl_git_pass(git_futils_readbuffer(&head, "repo/.git/HEAD")); + cl_assert_equal_s("foobar\n", head.ptr); + + git_buf_dispose(&head); +} + +void test_repo_template__initial_head_option_overrides_template_head(void) +{ + git_repository_init_options opts = GIT_REPOSITORY_INIT_OPTIONS_INIT; + git_buf head = GIT_BUF_INIT; + + opts.flags = GIT_REPOSITORY_INIT_MKPATH | GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE; + opts.initial_head = "manual"; + + setup_templates("template", true); + cl_git_mkfile("template/HEAD", "foobar\n"); + setup_repo("repo", &opts); + + cl_git_pass(git_futils_readbuffer(&head, "repo/.git/HEAD")); + cl_assert_equal_s("ref: refs/heads/manual\n", head.ptr); + + git_buf_dispose(&head); +} + +void test_repo_template__empty_template_path(void) +{ + git_repository_init_options opts = GIT_REPOSITORY_INIT_OPTIONS_INIT; + + opts.flags = GIT_REPOSITORY_INIT_MKPATH | GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE; + opts.template_path = ""; + + setup_repo("foo", &opts); +} |