8
#include "environment.h"
10
#include "object-file.h"
11
#include "parse-options.h"
14
#include "repository.h"
18
static int guess_repository_type(const char *git_dir)
28
if (!strcmp(".", git_dir))
31
cwd_is_git_dir = !strcmp(git_dir, cwd);
38
if (!strcmp(git_dir, ".git"))
40
slash = strrchr(git_dir, '/');
41
if (slash && !strcmp(slash, "/.git"))
51
static int shared_callback(const struct option *opt, const char *arg, int unset)
53
BUG_ON_OPT_NEG(unset);
54
*((int *) opt->value) = (arg) ? git_config_perm("arg", arg) : PERM_GROUP;
58
static const char *const init_db_usage[] = {
59
N_("git init [-q | --quiet] [--bare] [--template=<template-directory>]\n"
60
" [--separate-git-dir <git-dir>] [--object-format=<format>]\n"
61
" [--ref-format=<format>]\n"
62
" [-b <branch-name> | --initial-branch=<branch-name>]\n"
63
" [--shared[=<permissions>]] [<directory>]"),
73
int cmd_init_db(int argc, const char **argv, const char *prefix)
76
const char *real_git_dir = NULL;
77
const char *work_tree;
78
const char *template_dir = NULL;
79
unsigned int flags = 0;
80
const char *object_format = NULL;
81
const char *ref_format = NULL;
82
const char *initial_branch = NULL;
83
int hash_algo = GIT_HASH_UNKNOWN;
84
enum ref_storage_format ref_storage_format = REF_STORAGE_FORMAT_UNKNOWN;
85
int init_shared_repository = -1;
86
const struct option init_db_options[] = {
87
OPT_STRING(0, "template", &template_dir, N_("template-directory"),
88
N_("directory from which templates will be used")),
89
OPT_SET_INT(0, "bare", &is_bare_repository_cfg,
90
N_("create a bare repository"), 1),
91
{ OPTION_CALLBACK, 0, "shared", &init_shared_repository,
93
N_("specify that the git repository is to be shared amongst several users"),
94
PARSE_OPT_OPTARG | PARSE_OPT_NONEG, shared_callback, 0},
95
OPT_BIT('q', "quiet", &flags, N_("be quiet"), INIT_DB_QUIET),
96
OPT_STRING(0, "separate-git-dir", &real_git_dir, N_("gitdir"),
97
N_("separate git dir from working tree")),
98
OPT_STRING('b', "initial-branch", &initial_branch, N_("name"),
99
N_("override the name of the initial branch")),
100
OPT_STRING(0, "object-format", &object_format, N_("hash"),
101
N_("specify the hash algorithm to use")),
102
OPT_STRING(0, "ref-format", &ref_format, N_("format"),
103
N_("specify the reference format to use")),
107
argc = parse_options(argc, argv, prefix, init_db_options, init_db_usage, 0);
109
if (real_git_dir && is_bare_repository_cfg == 1)
110
die(_("options '%s' and '%s' cannot be used together"), "--separate-git-dir", "--bare");
112
if (real_git_dir && !is_absolute_path(real_git_dir))
113
real_git_dir = real_pathdup(real_git_dir, 1);
115
if (template_dir && *template_dir && !is_absolute_path(template_dir)) {
116
template_dir = absolute_pathdup(template_dir);
117
UNLEAK(template_dir);
123
if (chdir(argv[0]) < 0) {
131
saved = get_shared_repository();
132
set_shared_repository(0);
133
switch (safe_create_leading_directories_const(argv[0])) {
141
die_errno(_("cannot mkdir %s"), argv[0]);
144
set_shared_repository(saved);
145
if (mkdir(argv[0], 0777) < 0)
146
die_errno(_("cannot mkdir %s"), argv[0]);
150
die_errno(_("cannot chdir to %s"), argv[0]);
152
} else if (0 < argc) {
153
usage(init_db_usage[0]);
155
if (is_bare_repository_cfg == 1) {
156
char *cwd = xgetcwd();
157
setenv(GIT_DIR_ENVIRONMENT, cwd, argc > 0);
162
hash_algo = hash_algo_by_name(object_format);
163
if (hash_algo == GIT_HASH_UNKNOWN)
164
die(_("unknown hash algorithm '%s'"), object_format);
168
ref_storage_format = ref_storage_format_by_name(ref_format);
169
if (ref_storage_format == REF_STORAGE_FORMAT_UNKNOWN)
170
die(_("unknown ref storage format '%s'"), ref_format);
173
if (init_shared_repository != -1)
174
set_shared_repository(init_shared_repository);
180
git_dir = xstrdup_or_null(getenv(GIT_DIR_ENVIRONMENT));
181
work_tree = xstrdup_or_null(getenv(GIT_WORK_TREE_ENVIRONMENT));
182
if ((!git_dir || is_bare_repository_cfg == 1) && work_tree)
183
die(_("%s (or --work-tree=<directory>) not allowed without "
184
"specifying %s (or --git-dir=<directory>)"),
185
GIT_WORK_TREE_ENVIRONMENT,
186
GIT_DIR_ENVIRONMENT);
192
git_dir = DEFAULT_GIT_DIR_ENVIRONMENT;
202
struct strbuf sb = STRBUF_INIT;
204
p = read_gitfile_gently(git_dir, &err);
205
if (p && get_common_dir(&sb, p)) {
206
struct strbuf mainwt = STRBUF_INIT;
208
strbuf_addbuf(&mainwt, &sb);
209
strbuf_strip_suffix(&mainwt, "/.git");
210
if (chdir(mainwt.buf) < 0)
211
die_errno(_("cannot chdir to %s"), mainwt.buf);
212
strbuf_release(&mainwt);
213
git_dir = strbuf_detach(&sb, NULL);
218
if (is_bare_repository_cfg < 0)
219
is_bare_repository_cfg = guess_repository_type(git_dir);
221
if (!is_bare_repository_cfg) {
222
const char *git_dir_parent = strrchr(git_dir, '/');
223
if (git_dir_parent) {
224
char *rel = xstrndup(git_dir, git_dir_parent - git_dir);
225
git_work_tree_cfg = real_pathdup(rel, 1);
228
if (!git_work_tree_cfg)
229
git_work_tree_cfg = xgetcwd();
231
set_git_work_tree(work_tree);
233
set_git_work_tree(git_work_tree_cfg);
234
if (access(get_git_work_tree(), X_OK))
235
die_errno (_("Cannot access work tree '%s'"),
236
get_git_work_tree());
240
die(_("--separate-git-dir incompatible with bare repository"));
242
set_git_work_tree(work_tree);
245
UNLEAK(real_git_dir);
249
flags |= INIT_DB_EXIST_OK;
250
return init_db(git_dir, real_git_dir, template_dir, hash_algo,
251
ref_storage_format, initial_branch,
252
init_shared_repository, flags);