diff options
author | Patrick Steinhardt <ps@pks.im> | 2019-07-19 10:50:51 +0200 |
---|---|---|
committer | Patrick Steinhardt <ps@pks.im> | 2019-07-19 13:05:34 +0200 |
commit | 9d46f1675989c20663de80c003256bc586496771 (patch) | |
tree | 0c55f7ed4fc18c92c08159eaf2d1fb05c1554d29 | |
parent | f3134a8456f5b6604f6dd629c3ea124ae58a85f8 (diff) | |
download | libgit2-9d46f1675989c20663de80c003256bc586496771.tar.gz |
repository: do not initialize HEAD if it's provided by templates
When using templates to initialize a git repository, then git-init(1)
will copy over all contents of the template directory. These will be
preferred over the default ones created by git-init(1). While we mostly
do the same, there is the exception of "HEAD". While we do copy over the
template's HEAD file, afterwards we'll immediately re-initialize its
contents with either the default "ref: refs/origin/master" or the init
option's `initial_head` field.
Let's fix the inconsistency with upstream git-init(1) by not overwriting
the template HEAD, but only if the user hasn't set `opts.initial_head`.
If the `initial_head` field has been supplied, we should use that
indifferent from whether the template contained a HEAD file or not. Add
tests to verify we correctly use the template directory's HEAD file and
that `initial_head` overrides the template.
-rw-r--r-- | src/repository.c | 13 | ||||
-rw-r--r-- | tests/repo/template.c | 35 |
2 files changed, 47 insertions, 1 deletions
diff --git a/src/repository.c b/src/repository.c index eefc76ff2..d7079655f 100644 --- a/src/repository.c +++ b/src/repository.c @@ -2056,7 +2056,8 @@ int git_repository_init_ext( const char *given_repo, git_repository_init_options *opts) { - git_buf repo_path = GIT_BUF_INIT, wd_path = GIT_BUF_INIT, common_path = GIT_BUF_INIT; + git_buf repo_path = GIT_BUF_INIT, wd_path = GIT_BUF_INIT, + common_path = GIT_BUF_INIT, head_path = GIT_BUF_INIT; const char *wd; int error; @@ -2086,6 +2087,15 @@ int git_repository_init_ext( } 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; } @@ -2098,6 +2108,7 @@ int git_repository_init_ext( goto out; 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/template.c b/tests/repo/template.c index e86582ac3..7ccd93521 100644 --- a/tests/repo/template.c +++ b/tests/repo/template.c @@ -249,6 +249,41 @@ void test_repo_template__extended_with_template_and_shared_mode(void) 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; |