summaryrefslogtreecommitdiff
path: root/builtin/init-db.c
diff options
context:
space:
mode:
Diffstat (limited to 'builtin/init-db.c')
-rw-r--r--builtin/init-db.c79
1 files changed, 65 insertions, 14 deletions
diff --git a/builtin/init-db.c b/builtin/init-db.c
index 0b7222e..dcc45be 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,11 +195,15 @@ 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 struct repository_format *fmt)
+ const char *initial_branch,
+ const struct repository_format *fmt,
+ int quiet)
{
struct stat st1;
struct strbuf buf = STRBUF_INIT;
@@ -258,18 +258,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(quiet);
+
+ 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 +368,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 +395,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 +438,12 @@ 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,
+ flags & INIT_DB_QUIET);
+ if (reinit && initial_branch)
+ warning(_("re-init: ignored --initial-branch=%s"),
+ initial_branch);
create_object_directory();
@@ -528,6 +546,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 +560,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 +569,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 +646,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 +691,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 +702,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);
}