The 20th batch
[git.git] / builtin / init-db.c
blob7e00d57d654e6820c7ad2418cafc3a9aca815816
1 /*
2 * GIT - The information manager from hell
4 * Copyright (C) Linus Torvalds, 2005
5 */
6 #define USE_THE_REPOSITORY_VARIABLE
7 #include "builtin.h"
8 #include "abspath.h"
9 #include "environment.h"
10 #include "gettext.h"
11 #include "object-file.h"
12 #include "parse-options.h"
13 #include "path.h"
14 #include "refs.h"
15 #include "setup.h"
16 #include "strbuf.h"
18 static int guess_repository_type(const char *git_dir)
20 const char *slash;
21 char *cwd;
22 int cwd_is_git_dir;
25 * "GIT_DIR=. git init" is always bare.
26 * "GIT_DIR=`pwd` git init" too.
28 if (!strcmp(".", git_dir))
29 return 1;
30 cwd = xgetcwd();
31 cwd_is_git_dir = !strcmp(git_dir, cwd);
32 free(cwd);
33 if (cwd_is_git_dir)
34 return 1;
36 * "GIT_DIR=.git or GIT_DIR=something/.git is usually not.
38 if (!strcmp(git_dir, ".git"))
39 return 0;
40 slash = strrchr(git_dir, '/');
41 if (slash && !strcmp(slash, "/.git"))
42 return 0;
45 * Otherwise it is often bare. At this point
46 * we are just guessing.
48 return 1;
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;
55 return 0;
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>]"),
64 NULL
68 * If you want to, you can share the DB area with any number of branches.
69 * That has advantages: you can save space by sharing all the SHA1 objects.
70 * On the other hand, it might just make lookup slower and messier. You
71 * be the judge. The default case is to have one DB per managed directory.
73 int cmd_init_db(int argc,
74 const char **argv,
75 const char *prefix,
76 struct repository *repo UNUSED)
78 const char *git_dir;
79 const char *real_git_dir = NULL;
80 const char *work_tree;
81 const char *template_dir = NULL;
82 unsigned int flags = 0;
83 const char *object_format = NULL;
84 const char *ref_format = NULL;
85 const char *initial_branch = NULL;
86 int hash_algo = GIT_HASH_UNKNOWN;
87 enum ref_storage_format ref_storage_format = REF_STORAGE_FORMAT_UNKNOWN;
88 int init_shared_repository = -1;
89 const struct option init_db_options[] = {
90 OPT_STRING(0, "template", &template_dir, N_("template-directory"),
91 N_("directory from which templates will be used")),
92 OPT_SET_INT(0, "bare", &is_bare_repository_cfg,
93 N_("create a bare repository"), 1),
94 { OPTION_CALLBACK, 0, "shared", &init_shared_repository,
95 N_("permissions"),
96 N_("specify that the git repository is to be shared amongst several users"),
97 PARSE_OPT_OPTARG | PARSE_OPT_NONEG, shared_callback, 0},
98 OPT_BIT('q', "quiet", &flags, N_("be quiet"), INIT_DB_QUIET),
99 OPT_STRING(0, "separate-git-dir", &real_git_dir, N_("gitdir"),
100 N_("separate git dir from working tree")),
101 OPT_STRING('b', "initial-branch", &initial_branch, N_("name"),
102 N_("override the name of the initial branch")),
103 OPT_STRING(0, "object-format", &object_format, N_("hash"),
104 N_("specify the hash algorithm to use")),
105 OPT_STRING(0, "ref-format", &ref_format, N_("format"),
106 N_("specify the reference format to use")),
107 OPT_END()
110 argc = parse_options(argc, argv, prefix, init_db_options, init_db_usage, 0);
112 if (real_git_dir && is_bare_repository_cfg == 1)
113 die(_("options '%s' and '%s' cannot be used together"), "--separate-git-dir", "--bare");
115 if (real_git_dir && !is_absolute_path(real_git_dir))
116 real_git_dir = real_pathdup(real_git_dir, 1);
118 if (template_dir && *template_dir && !is_absolute_path(template_dir)) {
119 template_dir = absolute_pathdup(template_dir);
120 UNLEAK(template_dir);
123 if (argc == 1) {
124 int mkdir_tried = 0;
125 retry:
126 if (chdir(argv[0]) < 0) {
127 if (!mkdir_tried) {
128 int saved;
130 * At this point we haven't read any configuration,
131 * and we know shared_repository should always be 0;
132 * but just in case we play safe.
134 saved = get_shared_repository();
135 set_shared_repository(0);
136 switch (safe_create_leading_directories_const(argv[0])) {
137 case SCLD_OK:
138 case SCLD_PERMS:
139 break;
140 case SCLD_EXISTS:
141 errno = EEXIST;
142 /* fallthru */
143 default:
144 die_errno(_("cannot mkdir %s"), argv[0]);
145 break;
147 set_shared_repository(saved);
148 if (mkdir(argv[0], 0777) < 0)
149 die_errno(_("cannot mkdir %s"), argv[0]);
150 mkdir_tried = 1;
151 goto retry;
153 die_errno(_("cannot chdir to %s"), argv[0]);
155 } else if (0 < argc) {
156 usage(init_db_usage[0]);
158 if (is_bare_repository_cfg == 1) {
159 char *cwd = xgetcwd();
160 setenv(GIT_DIR_ENVIRONMENT, cwd, argc > 0);
161 free(cwd);
164 if (object_format) {
165 hash_algo = hash_algo_by_name(object_format);
166 if (hash_algo == GIT_HASH_UNKNOWN)
167 die(_("unknown hash algorithm '%s'"), object_format);
170 if (ref_format) {
171 ref_storage_format = ref_storage_format_by_name(ref_format);
172 if (ref_storage_format == REF_STORAGE_FORMAT_UNKNOWN)
173 die(_("unknown ref storage format '%s'"), ref_format);
176 if (init_shared_repository != -1)
177 set_shared_repository(init_shared_repository);
180 * GIT_WORK_TREE makes sense only in conjunction with GIT_DIR
181 * without --bare. Catch the error early.
183 git_dir = xstrdup_or_null(getenv(GIT_DIR_ENVIRONMENT));
184 work_tree = xstrdup_or_null(getenv(GIT_WORK_TREE_ENVIRONMENT));
185 if ((!git_dir || is_bare_repository_cfg == 1) && work_tree)
186 die(_("%s (or --work-tree=<directory>) not allowed without "
187 "specifying %s (or --git-dir=<directory>)"),
188 GIT_WORK_TREE_ENVIRONMENT,
189 GIT_DIR_ENVIRONMENT);
192 * Set up the default .git directory contents
194 if (!git_dir)
195 git_dir = DEFAULT_GIT_DIR_ENVIRONMENT;
198 * When --separate-git-dir is used inside a linked worktree, take
199 * care to ensure that the common .git/ directory is relocated, not
200 * the worktree-specific .git/worktrees/<id>/ directory.
202 if (real_git_dir) {
203 int err;
204 const char *p;
205 struct strbuf sb = STRBUF_INIT;
207 p = read_gitfile_gently(git_dir, &err);
208 if (p && get_common_dir(&sb, p)) {
209 struct strbuf mainwt = STRBUF_INIT;
211 strbuf_addbuf(&mainwt, &sb);
212 strbuf_strip_suffix(&mainwt, "/.git");
213 if (chdir(mainwt.buf) < 0)
214 die_errno(_("cannot chdir to %s"), mainwt.buf);
215 strbuf_release(&mainwt);
216 git_dir = strbuf_detach(&sb, NULL);
218 strbuf_release(&sb);
221 if (is_bare_repository_cfg < 0)
222 is_bare_repository_cfg = guess_repository_type(git_dir);
224 if (!is_bare_repository_cfg) {
225 const char *git_dir_parent = strrchr(git_dir, '/');
226 if (git_dir_parent) {
227 char *rel = xstrndup(git_dir, git_dir_parent - git_dir);
228 git_work_tree_cfg = real_pathdup(rel, 1);
229 free(rel);
231 if (!git_work_tree_cfg)
232 git_work_tree_cfg = xgetcwd();
233 if (work_tree)
234 set_git_work_tree(work_tree);
235 else
236 set_git_work_tree(git_work_tree_cfg);
237 if (access(repo_get_work_tree(the_repository), X_OK))
238 die_errno (_("Cannot access work tree '%s'"),
239 repo_get_work_tree(the_repository));
241 else {
242 if (real_git_dir)
243 die(_("--separate-git-dir incompatible with bare repository"));
244 if (work_tree)
245 set_git_work_tree(work_tree);
248 UNLEAK(real_git_dir);
249 UNLEAK(git_dir);
250 UNLEAK(work_tree);
252 flags |= INIT_DB_EXIST_OK;
253 return init_db(git_dir, real_git_dir, template_dir, hash_algo,
254 ref_storage_format, initial_branch,
255 init_shared_repository, flags);