diff options
Diffstat (limited to 'builtin/init-db.c')
-rw-r--r-- | builtin/init-db.c | 75 |
1 files changed, 62 insertions, 13 deletions
diff --git a/builtin/init-db.c b/builtin/init-db.c index 0b7222e718..01bc648d41 100644 --- a/builtin/init-db.c +++ b/builtin/init-db.c @@ -9,6 +9,7 @@ #include "builtin.h" #include "exec-cmd.h" #include "parse-options.h" +#include "worktree.h" #ifndef DEFAULT_GIT_TEMPLATE_DIR #define DEFAULT_GIT_TEMPLATE_DIR "/usr/share/git-core/templates" @@ -178,16 +179,11 @@ static int needs_work_tree_config(const char *git_dir, const char *work_tree) return 1; } -void initialize_repository_version(int hash_algo) +void initialize_repository_version(int hash_algo, int reinit) { char repo_version_string[10]; int repo_version = GIT_REPO_VERSION; -#ifndef ENABLE_SHA256 - if (hash_algo != GIT_HASH_SHA1) - die(_("The hash algorithm %s is not supported in this build."), hash_algos[hash_algo].name); -#endif - if (hash_algo != GIT_HASH_SHA1) repo_version = GIT_REPO_VERSION_READ; @@ -199,10 +195,13 @@ void initialize_repository_version(int hash_algo) if (hash_algo != GIT_HASH_SHA1) git_config_set("extensions.objectformat", hash_algos[hash_algo].name); + else if (reinit) + git_config_set_gently("extensions.objectformat", NULL); } static int create_default_files(const char *template_path, const char *original_git_dir, + const char *initial_branch, const struct repository_format *fmt) { struct stat st1; @@ -258,18 +257,29 @@ static int create_default_files(const char *template_path, die("failed to set up refs db: %s", err.buf); /* - * Create the default symlink from ".git/HEAD" to the "master" - * branch, if it does not exist yet. + * Point the HEAD symref to the initial branch with if HEAD does + * not yet exist. */ path = git_path_buf(&buf, "HEAD"); reinit = (!access(path, R_OK) || readlink(path, junk, sizeof(junk)-1) != -1); if (!reinit) { - if (create_symref("HEAD", "refs/heads/master", NULL) < 0) + char *ref; + + if (!initial_branch) + initial_branch = git_default_branch_name(); + + ref = xstrfmt("refs/heads/%s", initial_branch); + if (check_refname_format(ref, 0) < 0) + die(_("invalid initial branch name: '%s'"), + initial_branch); + + if (create_symref("HEAD", ref, NULL) < 0) exit(1); + free(ref); } - initialize_repository_version(fmt->hash_algo); + initialize_repository_version(fmt->hash_algo, 0); /* Check filemode trustability */ path = git_path_buf(&buf, "config"); @@ -357,6 +367,7 @@ static void separate_git_dir(const char *git_dir, const char *git_link) if (rename(src, git_dir)) die_errno(_("unable to move %s to %s"), src, git_dir); + repair_worktrees(NULL, NULL); } write_file(git_link, "gitdir: %s", git_dir); @@ -383,7 +394,8 @@ static void validate_hash_algorithm(struct repository_format *repo_fmt, int hash } int init_db(const char *git_dir, const char *real_git_dir, - const char *template_dir, int hash, unsigned int flags) + const char *template_dir, int hash, const char *initial_branch, + unsigned int flags) { int reinit; int exist_ok = flags & INIT_DB_EXIST_OK; @@ -425,7 +437,11 @@ int init_db(const char *git_dir, const char *real_git_dir, validate_hash_algorithm(&repo_fmt, hash); - reinit = create_default_files(template_dir, original_git_dir, &repo_fmt); + reinit = create_default_files(template_dir, original_git_dir, + initial_branch, &repo_fmt); + if (reinit && initial_branch) + warning(_("re-init: ignored --initial-branch=%s"), + initial_branch); create_object_directory(); @@ -528,6 +544,7 @@ int cmd_init_db(int argc, const char **argv, const char *prefix) const char *template_dir = NULL; unsigned int flags = 0; const char *object_format = NULL; + const char *initial_branch = NULL; int hash_algo = GIT_HASH_UNKNOWN; const struct option init_db_options[] = { OPT_STRING(0, "template", &template_dir, N_("template-directory"), @@ -541,6 +558,8 @@ int cmd_init_db(int argc, const char **argv, const char *prefix) OPT_BIT('q', "quiet", &flags, N_("be quiet"), INIT_DB_QUIET), OPT_STRING(0, "separate-git-dir", &real_git_dir, N_("gitdir"), N_("separate git dir from working tree")), + OPT_STRING('b', "initial-branch", &initial_branch, N_("name"), + N_("override the name of the initial branch")), OPT_STRING(0, "object-format", &object_format, N_("hash"), N_("specify the hash algorithm to use")), OPT_END() @@ -548,6 +567,9 @@ int cmd_init_db(int argc, const char **argv, const char *prefix) argc = parse_options(argc, argv, prefix, init_db_options, init_db_usage, 0); + if (real_git_dir && is_bare_repository_cfg == 1) + die(_("--separate-git-dir and --bare are mutually exclusive")); + if (real_git_dir && !is_absolute_path(real_git_dir)) real_git_dir = real_pathdup(real_git_dir, 1); @@ -622,6 +644,30 @@ int cmd_init_db(int argc, const char **argv, const char *prefix) if (!git_dir) git_dir = DEFAULT_GIT_DIR_ENVIRONMENT; + /* + * When --separate-git-dir is used inside a linked worktree, take + * care to ensure that the common .git/ directory is relocated, not + * the worktree-specific .git/worktrees/<id>/ directory. + */ + if (real_git_dir) { + int err; + const char *p; + struct strbuf sb = STRBUF_INIT; + + p = read_gitfile_gently(git_dir, &err); + if (p && get_common_dir(&sb, p)) { + struct strbuf mainwt = STRBUF_INIT; + + strbuf_addbuf(&mainwt, &sb); + strbuf_strip_suffix(&mainwt, "/.git"); + if (chdir(mainwt.buf) < 0) + die_errno(_("cannot chdir to %s"), mainwt.buf); + strbuf_release(&mainwt); + git_dir = strbuf_detach(&sb, NULL); + } + strbuf_release(&sb); + } + if (is_bare_repository_cfg < 0) is_bare_repository_cfg = guess_repository_type(git_dir); @@ -643,6 +689,8 @@ int cmd_init_db(int argc, const char **argv, const char *prefix) get_git_work_tree()); } else { + if (real_git_dir) + die(_("--separate-git-dir incompatible with bare repository")); if (work_tree) set_git_work_tree(work_tree); } @@ -652,5 +700,6 @@ int cmd_init_db(int argc, const char **argv, const char *prefix) UNLEAK(work_tree); flags |= INIT_DB_EXIST_OK; - return init_db(git_dir, real_git_dir, template_dir, hash_algo, flags); + return init_db(git_dir, real_git_dir, template_dir, hash_algo, + initial_branch, flags); } |