Provide API access to init_db()
The caller first calls set_git_dir() to specify the GIT_DIR, and then calls init_db() to initialize it. This also cleans up various parts of the code to account for the fact that everything is done with GIT_DIR set, so it's unnecessary to pass the specified directory around. Signed-off-by: Daniel Barkalow <barkalow@iabervon.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:

committed by
Junio C Hamano

parent
19757d80e5
commit
f225aeb278
@ -104,12 +104,14 @@ static void copy_templates_1(char *path, int baselen,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void copy_templates(const char *git_dir, int len, const char *template_dir)
|
static void copy_templates(const char *template_dir)
|
||||||
{
|
{
|
||||||
char path[PATH_MAX];
|
char path[PATH_MAX];
|
||||||
char template_path[PATH_MAX];
|
char template_path[PATH_MAX];
|
||||||
int template_len;
|
int template_len;
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
|
const char *git_dir = get_git_dir();
|
||||||
|
int len = strlen(git_dir);
|
||||||
|
|
||||||
if (!template_dir)
|
if (!template_dir)
|
||||||
template_dir = getenv(TEMPLATE_DIR_ENVIRONMENT);
|
template_dir = getenv(TEMPLATE_DIR_ENVIRONMENT);
|
||||||
@ -156,6 +158,8 @@ static void copy_templates(const char *git_dir, int len, const char *template_di
|
|||||||
}
|
}
|
||||||
|
|
||||||
memcpy(path, git_dir, len);
|
memcpy(path, git_dir, len);
|
||||||
|
if (len && path[len - 1] != '/')
|
||||||
|
path[len++] = '/';
|
||||||
path[len] = 0;
|
path[len] = 0;
|
||||||
copy_templates_1(path, len,
|
copy_templates_1(path, len,
|
||||||
template_path, template_len,
|
template_path, template_len,
|
||||||
@ -163,8 +167,9 @@ static void copy_templates(const char *git_dir, int len, const char *template_di
|
|||||||
closedir(dir);
|
closedir(dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int create_default_files(const char *git_dir, const char *template_path)
|
static int create_default_files(const char *template_path)
|
||||||
{
|
{
|
||||||
|
const char *git_dir = get_git_dir();
|
||||||
unsigned len = strlen(git_dir);
|
unsigned len = strlen(git_dir);
|
||||||
static char path[PATH_MAX];
|
static char path[PATH_MAX];
|
||||||
struct stat st1;
|
struct stat st1;
|
||||||
@ -183,19 +188,15 @@ static int create_default_files(const char *git_dir, const char *template_path)
|
|||||||
/*
|
/*
|
||||||
* Create .git/refs/{heads,tags}
|
* Create .git/refs/{heads,tags}
|
||||||
*/
|
*/
|
||||||
strcpy(path + len, "refs");
|
safe_create_dir(git_path("refs"), 1);
|
||||||
safe_create_dir(path, 1);
|
safe_create_dir(git_path("refs/heads"), 1);
|
||||||
strcpy(path + len, "refs/heads");
|
safe_create_dir(git_path("refs/tags"), 1);
|
||||||
safe_create_dir(path, 1);
|
|
||||||
strcpy(path + len, "refs/tags");
|
|
||||||
safe_create_dir(path, 1);
|
|
||||||
|
|
||||||
/* First copy the templates -- we might have the default
|
/* First copy the templates -- we might have the default
|
||||||
* config file there, in which case we would want to read
|
* config file there, in which case we would want to read
|
||||||
* from it after installing.
|
* from it after installing.
|
||||||
*/
|
*/
|
||||||
path[len] = 0;
|
copy_templates(template_path);
|
||||||
copy_templates(path, len, template_path);
|
|
||||||
|
|
||||||
git_config(git_default_config);
|
git_config(git_default_config);
|
||||||
|
|
||||||
@ -204,14 +205,10 @@ static int create_default_files(const char *git_dir, const char *template_path)
|
|||||||
* shared-repository settings, we would need to fix them up.
|
* shared-repository settings, we would need to fix them up.
|
||||||
*/
|
*/
|
||||||
if (shared_repository) {
|
if (shared_repository) {
|
||||||
path[len] = 0;
|
adjust_shared_perm(get_git_dir());
|
||||||
adjust_shared_perm(path);
|
adjust_shared_perm(git_path("refs"));
|
||||||
strcpy(path + len, "refs");
|
adjust_shared_perm(git_path("refs/heads"));
|
||||||
adjust_shared_perm(path);
|
adjust_shared_perm(git_path("refs/tags"));
|
||||||
strcpy(path + len, "refs/heads");
|
|
||||||
adjust_shared_perm(path);
|
|
||||||
strcpy(path + len, "refs/tags");
|
|
||||||
adjust_shared_perm(path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -251,9 +248,11 @@ static int create_default_files(const char *git_dir, const char *template_path)
|
|||||||
/* allow template config file to override the default */
|
/* allow template config file to override the default */
|
||||||
if (log_all_ref_updates == -1)
|
if (log_all_ref_updates == -1)
|
||||||
git_config_set("core.logallrefupdates", "true");
|
git_config_set("core.logallrefupdates", "true");
|
||||||
if (work_tree != git_work_tree_cfg)
|
if (prefixcmp(git_dir, work_tree) ||
|
||||||
|
strcmp(git_dir + strlen(work_tree), "/.git")) {
|
||||||
git_config_set("core.worktree", work_tree);
|
git_config_set("core.worktree", work_tree);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Check if symlink is supported in the work tree */
|
/* Check if symlink is supported in the work tree */
|
||||||
if (!reinit) {
|
if (!reinit) {
|
||||||
@ -272,106 +271,13 @@ static int create_default_files(const char *git_dir, const char *template_path)
|
|||||||
return reinit;
|
return reinit;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void guess_repository_type(const char *git_dir)
|
int init_db(const char *template_dir, unsigned int flags)
|
||||||
{
|
{
|
||||||
char cwd[PATH_MAX];
|
|
||||||
const char *slash;
|
|
||||||
|
|
||||||
if (0 <= is_bare_repository_cfg)
|
|
||||||
return;
|
|
||||||
if (!git_dir)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* "GIT_DIR=. git init" is always bare.
|
|
||||||
* "GIT_DIR=`pwd` git init" too.
|
|
||||||
*/
|
|
||||||
if (!strcmp(".", git_dir))
|
|
||||||
goto force_bare;
|
|
||||||
if (!getcwd(cwd, sizeof(cwd)))
|
|
||||||
die("cannot tell cwd");
|
|
||||||
if (!strcmp(git_dir, cwd))
|
|
||||||
goto force_bare;
|
|
||||||
/*
|
|
||||||
* "GIT_DIR=.git or GIT_DIR=something/.git is usually not.
|
|
||||||
*/
|
|
||||||
if (!strcmp(git_dir, ".git"))
|
|
||||||
return;
|
|
||||||
slash = strrchr(git_dir, '/');
|
|
||||||
if (slash && !strcmp(slash, "/.git"))
|
|
||||||
return;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Otherwise it is often bare. At this point
|
|
||||||
* we are just guessing.
|
|
||||||
*/
|
|
||||||
force_bare:
|
|
||||||
is_bare_repository_cfg = 1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char init_db_usage[] =
|
|
||||||
"git-init [-q | --quiet] [--template=<template-directory>] [--shared]";
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If you want to, you can share the DB area with any number of branches.
|
|
||||||
* That has advantages: you can save space by sharing all the SHA1 objects.
|
|
||||||
* On the other hand, it might just make lookup slower and messier. You
|
|
||||||
* be the judge. The default case is to have one DB per managed directory.
|
|
||||||
*/
|
|
||||||
int cmd_init_db(int argc, const char **argv, const char *prefix)
|
|
||||||
{
|
|
||||||
const char *git_dir;
|
|
||||||
const char *sha1_dir;
|
const char *sha1_dir;
|
||||||
const char *template_dir = NULL;
|
|
||||||
char *path;
|
char *path;
|
||||||
int len, i, reinit;
|
int len, reinit;
|
||||||
int quiet = 0;
|
|
||||||
|
|
||||||
for (i = 1; i < argc; i++, argv++) {
|
safe_create_dir(get_git_dir(), 0);
|
||||||
const char *arg = argv[1];
|
|
||||||
if (!prefixcmp(arg, "--template="))
|
|
||||||
template_dir = arg+11;
|
|
||||||
else if (!strcmp(arg, "--shared"))
|
|
||||||
shared_repository = PERM_GROUP;
|
|
||||||
else if (!prefixcmp(arg, "--shared="))
|
|
||||||
shared_repository = git_config_perm("arg", arg+9);
|
|
||||||
else if (!strcmp(arg, "-q") || !strcmp(arg, "--quiet"))
|
|
||||||
quiet = 1;
|
|
||||||
else
|
|
||||||
usage(init_db_usage);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* GIT_WORK_TREE makes sense only in conjunction with GIT_DIR
|
|
||||||
* without --bare. Catch the error early.
|
|
||||||
*/
|
|
||||||
git_dir = getenv(GIT_DIR_ENVIRONMENT);
|
|
||||||
if ((!git_dir || is_bare_repository_cfg == 1)
|
|
||||||
&& getenv(GIT_WORK_TREE_ENVIRONMENT))
|
|
||||||
die("%s (or --work-tree=<directory>) not allowed without "
|
|
||||||
"specifying %s (or --git-dir=<directory>)",
|
|
||||||
GIT_WORK_TREE_ENVIRONMENT,
|
|
||||||
GIT_DIR_ENVIRONMENT);
|
|
||||||
|
|
||||||
guess_repository_type(git_dir);
|
|
||||||
|
|
||||||
if (is_bare_repository_cfg <= 0) {
|
|
||||||
git_work_tree_cfg = xcalloc(PATH_MAX, 1);
|
|
||||||
if (!getcwd(git_work_tree_cfg, PATH_MAX))
|
|
||||||
die ("Cannot access current working directory.");
|
|
||||||
if (access(get_git_work_tree(), X_OK))
|
|
||||||
die ("Cannot access work tree '%s'",
|
|
||||||
get_git_work_tree());
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set up the default .git directory contents
|
|
||||||
*/
|
|
||||||
git_dir = getenv(GIT_DIR_ENVIRONMENT);
|
|
||||||
if (!git_dir)
|
|
||||||
git_dir = DEFAULT_GIT_DIR_ENVIRONMENT;
|
|
||||||
safe_create_dir(git_dir, 0);
|
|
||||||
|
|
||||||
/* Check to see if the repository version is right.
|
/* Check to see if the repository version is right.
|
||||||
* Note that a newly created repository does not have
|
* Note that a newly created repository does not have
|
||||||
@ -380,11 +286,8 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
|
|||||||
*/
|
*/
|
||||||
check_repository_format();
|
check_repository_format();
|
||||||
|
|
||||||
reinit = create_default_files(git_dir, template_dir);
|
reinit = create_default_files(template_dir);
|
||||||
|
|
||||||
/*
|
|
||||||
* And set up the object store.
|
|
||||||
*/
|
|
||||||
sha1_dir = get_object_directory();
|
sha1_dir = get_object_directory();
|
||||||
len = strlen(sha1_dir);
|
len = strlen(sha1_dir);
|
||||||
path = xmalloc(len + 40);
|
path = xmalloc(len + 40);
|
||||||
@ -414,11 +317,117 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
|
|||||||
git_config_set("receive.denyNonFastforwards", "true");
|
git_config_set("receive.denyNonFastforwards", "true");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!quiet)
|
if (!(flags & INIT_DB_QUIET))
|
||||||
printf("%s%s Git repository in %s/\n",
|
printf("%s%s Git repository in %s/\n",
|
||||||
reinit ? "Reinitialized existing" : "Initialized empty",
|
reinit ? "Reinitialized existing" : "Initialized empty",
|
||||||
shared_repository ? " shared" : "",
|
shared_repository ? " shared" : "",
|
||||||
git_dir);
|
get_git_dir());
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int guess_repository_type(const char *git_dir)
|
||||||
|
{
|
||||||
|
char cwd[PATH_MAX];
|
||||||
|
const char *slash;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "GIT_DIR=. git init" is always bare.
|
||||||
|
* "GIT_DIR=`pwd` git init" too.
|
||||||
|
*/
|
||||||
|
if (!strcmp(".", git_dir))
|
||||||
|
return 1;
|
||||||
|
if (!getcwd(cwd, sizeof(cwd)))
|
||||||
|
die("cannot tell cwd");
|
||||||
|
if (!strcmp(git_dir, cwd))
|
||||||
|
return 1;
|
||||||
|
/*
|
||||||
|
* "GIT_DIR=.git or GIT_DIR=something/.git is usually not.
|
||||||
|
*/
|
||||||
|
if (!strcmp(git_dir, ".git"))
|
||||||
|
return 0;
|
||||||
|
slash = strrchr(git_dir, '/');
|
||||||
|
if (slash && !strcmp(slash, "/.git"))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Otherwise it is often bare. At this point
|
||||||
|
* we are just guessing.
|
||||||
|
*/
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char init_db_usage[] =
|
||||||
|
"git-init [-q | --quiet] [--template=<template-directory>] [--shared]";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If you want to, you can share the DB area with any number of branches.
|
||||||
|
* That has advantages: you can save space by sharing all the SHA1 objects.
|
||||||
|
* On the other hand, it might just make lookup slower and messier. You
|
||||||
|
* be the judge. The default case is to have one DB per managed directory.
|
||||||
|
*/
|
||||||
|
int cmd_init_db(int argc, const char **argv, const char *prefix)
|
||||||
|
{
|
||||||
|
const char *git_dir;
|
||||||
|
const char *template_dir = NULL;
|
||||||
|
unsigned int flags = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 1; i < argc; i++, argv++) {
|
||||||
|
const char *arg = argv[1];
|
||||||
|
if (!prefixcmp(arg, "--template="))
|
||||||
|
template_dir = arg+11;
|
||||||
|
else if (!strcmp(arg, "--shared"))
|
||||||
|
shared_repository = PERM_GROUP;
|
||||||
|
else if (!prefixcmp(arg, "--shared="))
|
||||||
|
shared_repository = git_config_perm("arg", arg+9);
|
||||||
|
else if (!strcmp(arg, "-q") || !strcmp(arg, "--quiet"))
|
||||||
|
flags |= INIT_DB_QUIET;
|
||||||
|
else
|
||||||
|
usage(init_db_usage);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GIT_WORK_TREE makes sense only in conjunction with GIT_DIR
|
||||||
|
* without --bare. Catch the error early.
|
||||||
|
*/
|
||||||
|
git_dir = getenv(GIT_DIR_ENVIRONMENT);
|
||||||
|
if ((!git_dir || is_bare_repository_cfg == 1)
|
||||||
|
&& getenv(GIT_WORK_TREE_ENVIRONMENT))
|
||||||
|
die("%s (or --work-tree=<directory>) not allowed without "
|
||||||
|
"specifying %s (or --git-dir=<directory>)",
|
||||||
|
GIT_WORK_TREE_ENVIRONMENT,
|
||||||
|
GIT_DIR_ENVIRONMENT);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set up the default .git directory contents
|
||||||
|
*/
|
||||||
|
if (!git_dir)
|
||||||
|
git_dir = DEFAULT_GIT_DIR_ENVIRONMENT;
|
||||||
|
|
||||||
|
if (is_bare_repository_cfg < 0)
|
||||||
|
is_bare_repository_cfg = guess_repository_type(git_dir);
|
||||||
|
|
||||||
|
if (!is_bare_repository_cfg) {
|
||||||
|
if (git_dir) {
|
||||||
|
const char *git_dir_parent = strrchr(git_dir, '/');
|
||||||
|
if (git_dir_parent) {
|
||||||
|
char *rel = xstrndup(git_dir, git_dir_parent - git_dir);
|
||||||
|
git_work_tree_cfg = xstrdup(make_absolute_path(rel));
|
||||||
|
free(rel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!git_work_tree_cfg) {
|
||||||
|
git_work_tree_cfg = xcalloc(PATH_MAX, 1);
|
||||||
|
if (!getcwd(git_work_tree_cfg, PATH_MAX))
|
||||||
|
die ("Cannot access current working directory.");
|
||||||
|
}
|
||||||
|
if (access(get_git_work_tree(), X_OK))
|
||||||
|
die ("Cannot access work tree '%s'",
|
||||||
|
get_git_work_tree());
|
||||||
|
}
|
||||||
|
|
||||||
|
set_git_dir(make_absolute_path(git_dir));
|
||||||
|
|
||||||
|
return init_db(template_dir, flags);
|
||||||
|
}
|
||||||
|
4
cache.h
4
cache.h
@ -324,6 +324,10 @@ extern const char *prefix_filename(const char *prefix, int len, const char *path
|
|||||||
extern void verify_filename(const char *prefix, const char *name);
|
extern void verify_filename(const char *prefix, const char *name);
|
||||||
extern void verify_non_filename(const char *prefix, const char *name);
|
extern void verify_non_filename(const char *prefix, const char *name);
|
||||||
|
|
||||||
|
#define INIT_DB_QUIET 0x0001
|
||||||
|
|
||||||
|
extern int init_db(const char *template_dir, unsigned int flags);
|
||||||
|
|
||||||
#define alloc_nr(x) (((x)+16)*3/2)
|
#define alloc_nr(x) (((x)+16)*3/2)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Reference in New Issue
Block a user