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:
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 template_path[PATH_MAX];
|
||||
int template_len;
|
||||
DIR *dir;
|
||||
const char *git_dir = get_git_dir();
|
||||
int len = strlen(git_dir);
|
||||
|
||||
if (!template_dir)
|
||||
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);
|
||||
if (len && path[len - 1] != '/')
|
||||
path[len++] = '/';
|
||||
path[len] = 0;
|
||||
copy_templates_1(path, 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);
|
||||
}
|
||||
|
||||
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);
|
||||
static char path[PATH_MAX];
|
||||
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}
|
||||
*/
|
||||
strcpy(path + len, "refs");
|
||||
safe_create_dir(path, 1);
|
||||
strcpy(path + len, "refs/heads");
|
||||
safe_create_dir(path, 1);
|
||||
strcpy(path + len, "refs/tags");
|
||||
safe_create_dir(path, 1);
|
||||
safe_create_dir(git_path("refs"), 1);
|
||||
safe_create_dir(git_path("refs/heads"), 1);
|
||||
safe_create_dir(git_path("refs/tags"), 1);
|
||||
|
||||
/* First copy the templates -- we might have the default
|
||||
* config file there, in which case we would want to read
|
||||
* from it after installing.
|
||||
*/
|
||||
path[len] = 0;
|
||||
copy_templates(path, len, template_path);
|
||||
copy_templates(template_path);
|
||||
|
||||
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.
|
||||
*/
|
||||
if (shared_repository) {
|
||||
path[len] = 0;
|
||||
adjust_shared_perm(path);
|
||||
strcpy(path + len, "refs");
|
||||
adjust_shared_perm(path);
|
||||
strcpy(path + len, "refs/heads");
|
||||
adjust_shared_perm(path);
|
||||
strcpy(path + len, "refs/tags");
|
||||
adjust_shared_perm(path);
|
||||
adjust_shared_perm(get_git_dir());
|
||||
adjust_shared_perm(git_path("refs"));
|
||||
adjust_shared_perm(git_path("refs/heads"));
|
||||
adjust_shared_perm(git_path("refs/tags"));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -251,8 +248,10 @@ static int create_default_files(const char *git_dir, const char *template_path)
|
||||
/* allow template config file to override the default */
|
||||
if (log_all_ref_updates == -1)
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if symlink is supported in the work tree */
|
||||
@ -272,106 +271,13 @@ static int create_default_files(const char *git_dir, const char *template_path)
|
||||
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 *template_dir = NULL;
|
||||
char *path;
|
||||
int len, i, reinit;
|
||||
int quiet = 0;
|
||||
int len, reinit;
|
||||
|
||||
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"))
|
||||
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);
|
||||
safe_create_dir(get_git_dir(), 0);
|
||||
|
||||
/* Check to see if the repository version is right.
|
||||
* 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();
|
||||
|
||||
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();
|
||||
len = strlen(sha1_dir);
|
||||
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");
|
||||
}
|
||||
|
||||
if (!quiet)
|
||||
if (!(flags & INIT_DB_QUIET))
|
||||
printf("%s%s Git repository in %s/\n",
|
||||
reinit ? "Reinitialized existing" : "Initialized empty",
|
||||
shared_repository ? " shared" : "",
|
||||
git_dir);
|
||||
get_git_dir());
|
||||
|
||||
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_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)
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user