GIT 1.3.0 rc1
[git.git] / init-db.c
1 /*
2  * GIT - The information manager from hell
3  *
4  * Copyright (C) Linus Torvalds, 2005
5  */
6 #include "cache.h"
7
8 #ifndef DEFAULT_GIT_TEMPLATE_DIR
9 #define DEFAULT_GIT_TEMPLATE_DIR "/usr/share/git-core/templates/"
10 #endif
11
12 static void safe_create_dir(const char *dir, int share)
13 {
14         if (mkdir(dir, 0777) < 0) {
15                 if (errno != EEXIST) {
16                         perror(dir);
17                         exit(1);
18                 }
19         }
20         else if (share && adjust_shared_perm(dir))
21                 die("Could not make %s writable by group\n", dir);
22 }
23
24 static int copy_file(const char *dst, const char *src, int mode)
25 {
26         int fdi, fdo, status;
27
28         mode = (mode & 0111) ? 0777 : 0666;
29         if ((fdi = open(src, O_RDONLY)) < 0)
30                 return fdi;
31         if ((fdo = open(dst, O_WRONLY | O_CREAT | O_EXCL, mode)) < 0) {
32                 close(fdi);
33                 return fdo;
34         }
35         status = copy_fd(fdi, fdo);
36         close(fdo);
37
38         if (!status && adjust_shared_perm(dst))
39                 return -1;
40
41         return status;
42 }
43
44 static void copy_templates_1(char *path, int baselen,
45                              char *template, int template_baselen,
46                              DIR *dir)
47 {
48         struct dirent *de;
49
50         /* Note: if ".git/hooks" file exists in the repository being
51          * re-initialized, /etc/core-git/templates/hooks/update would
52          * cause git-init-db to fail here.  I think this is sane but
53          * it means that the set of templates we ship by default, along
54          * with the way the namespace under .git/ is organized, should
55          * be really carefully chosen.
56          */
57         safe_create_dir(path, 1);
58         while ((de = readdir(dir)) != NULL) {
59                 struct stat st_git, st_template;
60                 int namelen;
61                 int exists = 0;
62
63                 if (de->d_name[0] == '.')
64                         continue;
65                 namelen = strlen(de->d_name);
66                 if ((PATH_MAX <= baselen + namelen) ||
67                     (PATH_MAX <= template_baselen + namelen))
68                         die("insanely long template name %s", de->d_name);
69                 memcpy(path + baselen, de->d_name, namelen+1);
70                 memcpy(template + template_baselen, de->d_name, namelen+1);
71                 if (lstat(path, &st_git)) {
72                         if (errno != ENOENT)
73                                 die("cannot stat %s", path);
74                 }
75                 else
76                         exists = 1;
77
78                 if (lstat(template, &st_template))
79                         die("cannot stat template %s", template);
80
81                 if (S_ISDIR(st_template.st_mode)) {
82                         DIR *subdir = opendir(template);
83                         int baselen_sub = baselen + namelen;
84                         int template_baselen_sub = template_baselen + namelen;
85                         if (!subdir)
86                                 die("cannot opendir %s", template);
87                         path[baselen_sub++] =
88                                 template[template_baselen_sub++] = '/';
89                         path[baselen_sub] =
90                                 template[template_baselen_sub] = 0;
91                         copy_templates_1(path, baselen_sub,
92                                          template, template_baselen_sub,
93                                          subdir);
94                         closedir(subdir);
95                 }
96                 else if (exists)
97                         continue;
98                 else if (S_ISLNK(st_template.st_mode)) {
99                         char lnk[256];
100                         int len;
101                         len = readlink(template, lnk, sizeof(lnk));
102                         if (len < 0)
103                                 die("cannot readlink %s", template);
104                         if (sizeof(lnk) <= len)
105                                 die("insanely long symlink %s", template);
106                         lnk[len] = 0;
107                         if (symlink(lnk, path))
108                                 die("cannot symlink %s %s", lnk, path);
109                 }
110                 else if (S_ISREG(st_template.st_mode)) {
111                         if (copy_file(path, template, st_template.st_mode))
112                                 die("cannot copy %s to %s", template, path);
113                 }
114                 else
115                         error("ignoring template %s", template);
116         }
117 }
118
119 static void copy_templates(const char *git_dir, int len, char *template_dir)
120 {
121         char path[PATH_MAX];
122         char template_path[PATH_MAX];
123         int template_len;
124         DIR *dir;
125
126         if (!template_dir)
127                 template_dir = DEFAULT_GIT_TEMPLATE_DIR;
128         strcpy(template_path, template_dir);
129         template_len = strlen(template_path);
130         if (template_path[template_len-1] != '/') {
131                 template_path[template_len++] = '/';
132                 template_path[template_len] = 0;
133         }
134         dir = opendir(template_path);
135         if (!dir) {
136                 fprintf(stderr, "warning: templates not found %s\n",
137                         template_dir);
138                 return;
139         }
140
141         /* Make sure that template is from the correct vintage */
142         strcpy(template_path + template_len, "config");
143         repository_format_version = 0;
144         git_config_from_file(check_repository_format_version,
145                              template_path);
146         template_path[template_len] = 0;
147
148         if (repository_format_version &&
149             repository_format_version != GIT_REPO_VERSION) {
150                 fprintf(stderr, "warning: not copying templates of "
151                         "a wrong format version %d from '%s'\n",
152                         repository_format_version,
153                         template_dir);
154                 closedir(dir);
155                 return;
156         }
157
158         memcpy(path, git_dir, len);
159         path[len] = 0;
160         copy_templates_1(path, len,
161                          template_path, template_len,
162                          dir);
163         closedir(dir);
164 }
165
166 static void create_default_files(const char *git_dir, char *template_path)
167 {
168         unsigned len = strlen(git_dir);
169         static char path[PATH_MAX];
170         unsigned char sha1[20];
171         struct stat st1;
172         char repo_version_string[10];
173
174         if (len > sizeof(path)-50)
175                 die("insane git directory %s", git_dir);
176         memcpy(path, git_dir, len);
177
178         if (len && path[len-1] != '/')
179                 path[len++] = '/';
180
181         /*
182          * Create .git/refs/{heads,tags}
183          */
184         strcpy(path + len, "refs");
185         safe_create_dir(path, 1);
186         strcpy(path + len, "refs/heads");
187         safe_create_dir(path, 1);
188         strcpy(path + len, "refs/tags");
189         safe_create_dir(path, 1);
190
191         /* First copy the templates -- we might have the default
192          * config file there, in which case we would want to read
193          * from it after installing.
194          */
195         path[len] = 0;
196         copy_templates(path, len, template_path);
197
198         git_config(git_default_config);
199
200         /*
201          * Create the default symlink from ".git/HEAD" to the "master"
202          * branch, if it does not exist yet.
203          */
204         strcpy(path + len, "HEAD");
205         if (read_ref(path, sha1) < 0) {
206                 if (create_symref(path, "refs/heads/master") < 0)
207                         exit(1);
208         }
209
210         /* This forces creation of new config file */
211         sprintf(repo_version_string, "%d", GIT_REPO_VERSION);
212         git_config_set("core.repositoryformatversion", repo_version_string);
213
214         path[len] = 0;
215         strcpy(path + len, "config");
216
217         /* Check filemode trustability */
218         if (!lstat(path, &st1)) {
219                 struct stat st2;
220                 int filemode = (!chmod(path, st1.st_mode ^ S_IXUSR) &&
221                                 !lstat(path, &st2) &&
222                                 st1.st_mode != st2.st_mode);
223                 git_config_set("core.filemode",
224                                filemode ? "true" : "false");
225         }
226 }
227
228 static const char init_db_usage[] =
229 "git-init-db [--template=<template-directory>] [--shared]";
230
231 /*
232  * If you want to, you can share the DB area with any number of branches.
233  * That has advantages: you can save space by sharing all the SHA1 objects.
234  * On the other hand, it might just make lookup slower and messier. You
235  * be the judge.  The default case is to have one DB per managed directory.
236  */
237 int main(int argc, char **argv)
238 {
239         const char *git_dir;
240         const char *sha1_dir;
241         char *path, *template_dir = NULL;
242         int len, i;
243
244         for (i = 1; i < argc; i++, argv++) {
245                 char *arg = argv[1];
246                 if (!strncmp(arg, "--template=", 11))
247                         template_dir = arg+11;
248                 else if (!strcmp(arg, "--shared"))
249                         shared_repository = 1;
250                 else
251                         die(init_db_usage);
252         }
253
254         /*
255          * Set up the default .git directory contents
256          */
257         git_dir = getenv(GIT_DIR_ENVIRONMENT);
258         if (!git_dir) {
259                 git_dir = DEFAULT_GIT_DIR_ENVIRONMENT;
260                 fprintf(stderr, "defaulting to local storage area\n");
261         }
262         safe_create_dir(git_dir, 0);
263
264         /* Check to see if the repository version is right.
265          * Note that a newly created repository does not have
266          * config file, so this will not fail.  What we are catching
267          * is an attempt to reinitialize new repository with an old tool.
268          */
269         check_repository_format();
270
271         create_default_files(git_dir, template_dir);
272
273         /*
274          * And set up the object store.
275          */
276         sha1_dir = get_object_directory();
277         len = strlen(sha1_dir);
278         path = xmalloc(len + 40);
279         memcpy(path, sha1_dir, len);
280
281         safe_create_dir(sha1_dir, 1);
282         strcpy(path+len, "/pack");
283         safe_create_dir(path, 1);
284         strcpy(path+len, "/info");
285         safe_create_dir(path, 1);
286
287         if (shared_repository)
288                 git_config_set("core.sharedRepository", "true");
289
290         return 0;
291 }