setup: split up concerns of `init_db()`
The function `init_db()` is responsible for creating the on-disk
directory structure required for a Git repository. It is used by both
git-init(1) and git-clone(1), and because their expected behaviour is
different we support a couple of flags:
- The `QUIET` flag controls whether the command is quiet or not. For
git-init(1) this is user-controllable, whereas for git-clone(1)
we're always quiet.
- The `EXIST_OK` flag controls whether a preexisting repository is
okay or not. For git-init(1) it is, for git-clone(1) it's not.
- The `SKIP_REFDB` flag controls whether the reference database should
already be created or not. For git-init(1) we do, but for
git-clone(1) we don't because it does not yet know about the default
branch and about the remote object hash.
Furthermore, we're about to add another divergence in behaviour, where
we have to also skip creation of the object database in git-clone(1).
This is becoming quite cumbersome though.
Instead of introducing another flag, start to split up concerns of the
function so that we never create the reference or object database. This
becomes the responsibility of the caller, which is thus free to defer
their creation to a later point in time. This lets us get rid of most of
the divergent behaviour:
- We don't need the `SKIP_REFDB` and a potential `SKIP_ODB` flags
anymore.
- We don't need the `QUIET` flag anymore, as nothing prints output
except for the final status message that tells the user that the
repository has been (re)initialized. But as this message is specific
to git-init(1), we can easily move it there.
The only piece of information we still have to convey is whether or not
reinitialization of a preexisting repository is okay. This is handled by
a new `reinit_ok` pointer that, if non-`NULL`, indicates that it is okay
to reinitialize the repository. Furthermore, the pointer will be written
to to indicate whether the repository was reinitialized or not, which we
need in git-init(1) to print the correct initialization message.
With these refactorings, `init_db()` is named quite misleadingly though,
as we don't create any of the reference or object databases anymore.
Rename it to `create_repository()`.
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
next
parent
02e44450dd
commit
20e38cba39
|
|
@ -1185,10 +1185,10 @@ int cmd_clone(int argc,
|
|||
* repository, and reference backends may persist that information into
|
||||
* their on-disk data structures.
|
||||
*/
|
||||
init_db(the_repository, git_dir, real_git_dir, work_tree, option_template,
|
||||
GIT_HASH_UNKNOWN, ref_storage_format, NULL,
|
||||
do_not_override_repo_unix_permissions,
|
||||
INIT_DB_QUIET | INIT_DB_SKIP_REFDB);
|
||||
create_repository(the_repository, git_dir, real_git_dir, work_tree,
|
||||
option_template, GIT_HASH_UNKNOWN, ref_storage_format,
|
||||
do_not_override_repo_unix_permissions, NULL);
|
||||
create_object_database(the_repository);
|
||||
|
||||
if (real_git_dir) {
|
||||
free((char *)git_dir);
|
||||
|
|
@ -1445,6 +1445,7 @@ int cmd_clone(int argc,
|
|||
initialize_repository_version(the_repository, hash_algo, the_repository->ref_storage_format, 1);
|
||||
repo_set_hash_algo(the_repository, hash_algo);
|
||||
create_reference_database(the_repository, NULL, 1);
|
||||
startup_info->have_repository = 1;
|
||||
|
||||
/*
|
||||
* Before fetching from the remote, download and install bundle
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ int cmd_init_db(int argc,
|
|||
char *work_tree = NULL;
|
||||
const char *template_dir = NULL;
|
||||
char *template_dir_to_free = NULL;
|
||||
unsigned int flags = 0;
|
||||
int quiet = 0;
|
||||
int bare = startup_info->force_bare_repository ? 1 : -1;
|
||||
const char *object_format = NULL;
|
||||
const char *ref_format = NULL;
|
||||
|
|
@ -102,7 +102,7 @@ int cmd_init_db(int argc,
|
|||
.flags = PARSE_OPT_OPTARG | PARSE_OPT_NONEG,
|
||||
.callback = shared_callback
|
||||
},
|
||||
OPT_BIT('q', "quiet", &flags, N_("be quiet"), INIT_DB_QUIET),
|
||||
OPT_BOOL('q', "quiet", &quiet, N_("be 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"),
|
||||
|
|
@ -113,7 +113,7 @@ int cmd_init_db(int argc,
|
|||
N_("specify the reference format to use")),
|
||||
OPT_END()
|
||||
};
|
||||
int ret;
|
||||
int reinit;
|
||||
|
||||
argc = parse_options(argc, argv, prefix, init_db_options, init_db_usage, 0);
|
||||
|
||||
|
|
@ -247,14 +247,30 @@ int cmd_init_db(int argc,
|
|||
die(_("--separate-git-dir incompatible with bare repository"));
|
||||
}
|
||||
|
||||
flags |= INIT_DB_EXIST_OK;
|
||||
ret = init_db(the_repository, git_dir, real_git_dir, work_tree,
|
||||
template_dir, hash_algo, ref_storage_format, initial_branch,
|
||||
init_shared_repository, flags);
|
||||
create_repository(the_repository, git_dir, real_git_dir, work_tree,
|
||||
template_dir, hash_algo, ref_storage_format,
|
||||
init_shared_repository, &reinit);
|
||||
create_reference_database(the_repository, initial_branch, quiet);
|
||||
create_object_database(the_repository);
|
||||
|
||||
if (!quiet) {
|
||||
int len = strlen(git_dir);
|
||||
|
||||
if (reinit)
|
||||
printf(repo_settings_get_shared_repository(the_repository)
|
||||
? _("Reinitialized existing shared Git repository in %s%s\n")
|
||||
: _("Reinitialized existing Git repository in %s%s\n"),
|
||||
git_dir, len && git_dir[len-1] != '/' ? "/" : "");
|
||||
else
|
||||
printf(repo_settings_get_shared_repository(the_repository)
|
||||
? _("Initialized empty shared Git repository in %s%s\n")
|
||||
: _("Initialized empty Git repository in %s%s\n"),
|
||||
git_dir, len && git_dir[len-1] != '/' ? "/" : "");
|
||||
}
|
||||
|
||||
free(template_dir_to_free);
|
||||
free(real_git_dir_to_free);
|
||||
free(work_tree);
|
||||
free(git_dir);
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
54
setup.c
54
setup.c
|
|
@ -2647,7 +2647,7 @@ static int create_default_files(struct repository *repo,
|
|||
return reinit;
|
||||
}
|
||||
|
||||
static void create_object_database(struct repository *repo)
|
||||
void create_object_database(struct repository *repo)
|
||||
{
|
||||
/*
|
||||
* Create the "objects" directory in the common directory. This is done
|
||||
|
|
@ -2822,17 +2822,17 @@ static void repository_format_configure(struct repository_format *repo_fmt,
|
|||
}
|
||||
}
|
||||
|
||||
int init_db(struct repository *repo,
|
||||
const char *git_dir,
|
||||
const char *real_git_dir,
|
||||
const char *worktree,
|
||||
const char *template_dir, int hash,
|
||||
enum ref_storage_format ref_storage_format,
|
||||
const char *initial_branch,
|
||||
int init_shared_repository, unsigned int flags)
|
||||
void create_repository(struct repository *repo,
|
||||
const char *git_dir,
|
||||
const char *real_git_dir,
|
||||
const char *worktree,
|
||||
const char *template_dir,
|
||||
int hash,
|
||||
enum ref_storage_format ref_storage_format,
|
||||
int init_shared_repository,
|
||||
int *reinit_ok)
|
||||
{
|
||||
int reinit;
|
||||
int exist_ok = flags & INIT_DB_EXIST_OK;
|
||||
int reinit_ignored;
|
||||
char *original_git_dir = real_pathdup(git_dir, 1);
|
||||
struct repository_format repo_fmt = REPOSITORY_FORMAT_INIT;
|
||||
struct strbuf err = STRBUF_INIT;
|
||||
|
|
@ -2840,10 +2840,10 @@ int init_db(struct repository *repo,
|
|||
if (real_git_dir) {
|
||||
struct stat st;
|
||||
|
||||
if (!exist_ok && !stat(git_dir, &st))
|
||||
if (!reinit_ok && !stat(git_dir, &st))
|
||||
die(_("%s already exists"), git_dir);
|
||||
|
||||
if (!exist_ok && !stat(real_git_dir, &st))
|
||||
if (!reinit_ok && !stat(real_git_dir, &st))
|
||||
die(_("%s already exists"), real_git_dir);
|
||||
|
||||
apply_and_export_relative_gitdir(repo, real_git_dir, 1);
|
||||
|
|
@ -2877,8 +2877,10 @@ int init_db(struct repository *repo,
|
|||
|
||||
safe_create_dir(repo, git_dir, 0);
|
||||
|
||||
reinit = create_default_files(repo, template_dir, original_git_dir,
|
||||
&repo_fmt, init_shared_repository);
|
||||
if (!reinit_ok)
|
||||
reinit_ok = &reinit_ignored;
|
||||
*reinit_ok = create_default_files(repo, template_dir, original_git_dir,
|
||||
&repo_fmt, init_shared_repository);
|
||||
|
||||
if (repo_settings_get_shared_repository(repo)) {
|
||||
char buf[10];
|
||||
|
|
@ -2901,29 +2903,7 @@ int init_db(struct repository *repo,
|
|||
repo_config_set(repo, "receive.denyNonFastforwards", "true");
|
||||
}
|
||||
|
||||
if (!(flags & INIT_DB_SKIP_REFDB))
|
||||
create_reference_database(repo, initial_branch, flags & INIT_DB_QUIET);
|
||||
create_object_database(repo);
|
||||
|
||||
startup_info->have_repository = 1;
|
||||
|
||||
if (!(flags & INIT_DB_QUIET)) {
|
||||
int len = strlen(git_dir);
|
||||
|
||||
if (reinit)
|
||||
printf(repo_settings_get_shared_repository(repo)
|
||||
? _("Reinitialized existing shared Git repository in %s%s\n")
|
||||
: _("Reinitialized existing Git repository in %s%s\n"),
|
||||
git_dir, len && git_dir[len-1] != '/' ? "/" : "");
|
||||
else
|
||||
printf(repo_settings_get_shared_repository(repo)
|
||||
? _("Initialized empty shared Git repository in %s%s\n")
|
||||
: _("Initialized empty Git repository in %s%s\n"),
|
||||
git_dir, len && git_dir[len-1] != '/' ? "/" : "");
|
||||
}
|
||||
|
||||
clear_repository_format(&repo_fmt);
|
||||
strbuf_release(&err);
|
||||
free(original_git_dir);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
43
setup.h
43
setup.h
|
|
@ -256,24 +256,45 @@ int apply_repository_format(struct repository *repo,
|
|||
|
||||
const char *get_template_dir(const char *option_template);
|
||||
|
||||
#define INIT_DB_QUIET (1 << 0)
|
||||
#define INIT_DB_EXIST_OK (1 << 1)
|
||||
#define INIT_DB_SKIP_REFDB (1 << 2)
|
||||
/*
|
||||
* Create the repository by creating the necessary directory structures,
|
||||
* setting up the configuration and configuring the repository's format. If
|
||||
* `template_dir` is set, copy over templates from that directory. Furthermore,
|
||||
* if and only if `reinit_ok` is a non-NULL pointer, then the function may
|
||||
* reinitialize a preexisting repository. In that case, the pointer will be set
|
||||
* to `1` in case the repo was reinitialized and `0` if it didn't exist yet.
|
||||
*
|
||||
* Note that this function does not create the reference and object databases.
|
||||
*/
|
||||
void create_repository(struct repository *repo,
|
||||
const char *git_dir,
|
||||
const char *real_git_dir,
|
||||
const char *worktree,
|
||||
const char *template_dir,
|
||||
int hash_algo,
|
||||
enum ref_storage_format ref_storage_format,
|
||||
int init_shared_repository,
|
||||
int *reinit_ok);
|
||||
|
||||
int init_db(struct repository *repo,
|
||||
const char *git_dir,
|
||||
const char *real_git_dir,
|
||||
const char *worktree,
|
||||
const char *template_dir, int hash_algo,
|
||||
enum ref_storage_format ref_storage_format,
|
||||
const char *initial_branch, int init_shared_repository,
|
||||
unsigned int flags);
|
||||
void initialize_repository_version(struct repository *repo,
|
||||
int hash_algo,
|
||||
enum ref_storage_format ref_storage_format,
|
||||
int reinit);
|
||||
|
||||
/*
|
||||
* Create the reference database for the repository. The repository and its ref
|
||||
* storage format must have already been configured properly before calling
|
||||
* this function. When set, `initial_branch` overrides the default branch that
|
||||
* HEAD will point to.
|
||||
*/
|
||||
void create_reference_database(struct repository *repo, const char *initial_branch, int quiet);
|
||||
|
||||
/*
|
||||
* Create the object database for the repository. The repository must have
|
||||
* already been configured properly before calling this function.
|
||||
*/
|
||||
void create_object_database(struct repository *repo);
|
||||
|
||||
/*
|
||||
* NOTE NOTE NOTE!!
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue