#include "string-list.h"
#include "chdir-notify.h"
#include "path.h"
-#include "promisor-remote.h"
#include "quote.h"
#include "trace2.h"
#include "worktree.h"
"extensions.objectformat", value);
data->hash_algo = format;
return EXTENSION_OK;
+ } else if (!strcmp(ext, "refstorage")) {
+ unsigned int format;
+
+ if (!value)
+ return config_error_nonbool(var);
+ format = ref_storage_format_by_name(value);
+ if (format == REF_STORAGE_FORMAT_UNKNOWN)
+ return error(_("invalid value for '%s': '%s'"),
+ "extensions.refstorage", value);
+ data->ref_storage_format = format;
+ return EXTENSION_OK;
}
return EXTENSION_UNKNOWN;
}
}
if (startup_info->have_repository) {
repo_set_hash_algo(the_repository, repo_fmt.hash_algo);
+ repo_set_ref_storage_format(the_repository,
+ repo_fmt.ref_storage_format);
the_repository->repository_format_worktree_config =
repo_fmt.worktree_config;
/* take ownership of repo_fmt.partial_clone */
check_repository_format_gently(get_git_dir(), fmt, NULL);
startup_info->have_repository = 1;
repo_set_hash_algo(the_repository, fmt->hash_algo);
+ repo_set_ref_storage_format(the_repository,
+ fmt->ref_storage_format);
the_repository->repository_format_worktree_config =
fmt->worktree_config;
the_repository->repository_format_partial_clone =
return 1;
}
-void initialize_repository_version(int hash_algo, int reinit)
+void initialize_repository_version(int hash_algo,
+ unsigned int ref_storage_format,
+ int reinit)
{
char repo_version_string[10];
int repo_version = GIT_REPO_VERSION;
- if (hash_algo != GIT_HASH_SHA1)
+ if (hash_algo != GIT_HASH_SHA1 ||
+ ref_storage_format != REF_STORAGE_FORMAT_FILES)
repo_version = GIT_REPO_VERSION_READ;
/* This forces creation of new config file */
hash_algos[hash_algo].name);
else if (reinit)
git_config_set_gently("extensions.objectformat", NULL);
+
+ if (ref_storage_format != REF_STORAGE_FORMAT_FILES)
+ git_config_set("extensions.refstorage",
+ ref_storage_format_to_name(ref_storage_format));
+}
+
+static int is_reinit(void)
+{
+ struct strbuf buf = STRBUF_INIT;
+ char junk[2];
+ int ret;
+
+ git_path_buf(&buf, "HEAD");
+ ret = !access(buf.buf, R_OK) || readlink(buf.buf, junk, sizeof(junk) - 1) != -1;
+ strbuf_release(&buf);
+ return ret;
+}
+
+void create_reference_database(unsigned int ref_storage_format,
+ const char *initial_branch, int quiet)
+{
+ struct strbuf err = STRBUF_INIT;
+ int reinit = is_reinit();
+
+ repo_set_ref_storage_format(the_repository, ref_storage_format);
+ if (refs_init_db(get_main_ref_store(the_repository), 0, &err))
+ die("failed to set up refs db: %s", err.buf);
+
+ /*
+ * Point the HEAD symref to the initial branch with if HEAD does
+ * not yet exist.
+ */
+ if (!reinit) {
+ 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);
+ }
+
+ if (reinit && initial_branch)
+ warning(_("re-init: ignored --initial-branch=%s"),
+ initial_branch);
+
+ strbuf_release(&err);
}
static int create_default_files(const char *template_path,
const char *original_git_dir,
- const char *initial_branch,
const struct repository_format *fmt,
int prev_bare_repository,
- int init_shared_repository,
- int quiet)
+ int init_shared_repository)
{
struct stat st1;
struct strbuf buf = STRBUF_INIT;
char *path;
- char junk[2];
int reinit;
int filemode;
- struct strbuf err = STRBUF_INIT;
const char *init_template_dir = NULL;
const char *work_tree = get_git_work_tree();
reset_shared_repository();
git_config(git_default_config, NULL);
+ reinit = is_reinit();
+
/*
* We must make sure command-line options continue to override any
* values we might have just re-read from the config.
adjust_shared_perm(get_git_dir());
}
- /*
- * We need to create a "refs" dir in any case so that older
- * versions of git can tell that this is a repository.
- */
- safe_create_dir(git_path("refs"), 1);
- adjust_shared_perm(git_path("refs"));
-
- if (refs_init_db(&err))
- die("failed to set up refs db: %s", err.buf);
-
- /*
- * 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) {
- 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, 0);
+ initialize_repository_version(fmt->hash_algo, fmt->ref_storage_format, 0);
/* Check filemode trustability */
path = git_path_buf(&buf, "config");
}
}
+static void validate_ref_storage_format(struct repository_format *repo_fmt,
+ unsigned int format)
+{
+ const char *name = getenv("GIT_DEFAULT_REF_FORMAT");
+
+ if (repo_fmt->version >= 0 &&
+ format != REF_STORAGE_FORMAT_UNKNOWN &&
+ format != repo_fmt->ref_storage_format) {
+ die(_("attempt to reinitialize repository with different reference storage format"));
+ } else if (format != REF_STORAGE_FORMAT_UNKNOWN) {
+ repo_fmt->ref_storage_format = format;
+ } else if (name) {
+ format = ref_storage_format_by_name(name);
+ if (format == REF_STORAGE_FORMAT_UNKNOWN)
+ die(_("unknown ref storage format '%s'"), name);
+ repo_fmt->ref_storage_format = format;
+ }
+}
+
int init_db(const char *git_dir, const char *real_git_dir,
- const char *template_dir, int hash, const char *initial_branch,
+ const char *template_dir, int hash,
+ unsigned int ref_storage_format,
+ const char *initial_branch,
int init_shared_repository, unsigned int flags)
{
int reinit;
check_repository_format(&repo_fmt);
validate_hash_algorithm(&repo_fmt, hash);
+ validate_ref_storage_format(&repo_fmt, ref_storage_format);
reinit = create_default_files(template_dir, original_git_dir,
- initial_branch, &repo_fmt,
- prev_bare_repository,
- init_shared_repository,
- flags & INIT_DB_QUIET);
- if (reinit && initial_branch)
- warning(_("re-init: ignored --initial-branch=%s"),
- initial_branch);
+ &repo_fmt, prev_bare_repository,
+ init_shared_repository);
+
+ /*
+ * Now that we have set up both the hash algorithm and the ref storage
+ * format we can update the repository's settings accordingly.
+ */
+ repo_set_hash_algo(the_repository, repo_fmt.hash_algo);
+ repo_set_ref_storage_format(the_repository, repo_fmt.ref_storage_format);
+ if (!(flags & INIT_DB_SKIP_REFDB))
+ create_reference_database(repo_fmt.ref_storage_format,
+ initial_branch, flags & INIT_DB_QUIET);
create_object_directory();
if (get_shared_repository()) {