Coverage Report

Created: 2024-09-08 06:23

/src/git/setup.c
Line
Count
Source (jump to first uncovered line)
1
#define USE_THE_REPOSITORY_VARIABLE
2
3
#include "git-compat-util.h"
4
#include "abspath.h"
5
#include "copy.h"
6
#include "environment.h"
7
#include "exec-cmd.h"
8
#include "gettext.h"
9
#include "hex.h"
10
#include "object-name.h"
11
#include "refs.h"
12
#include "repository.h"
13
#include "config.h"
14
#include "dir.h"
15
#include "setup.h"
16
#include "string-list.h"
17
#include "chdir-notify.h"
18
#include "path.h"
19
#include "quote.h"
20
#include "trace2.h"
21
#include "worktree.h"
22
#include "exec-cmd.h"
23
24
static int inside_git_dir = -1;
25
static int inside_work_tree = -1;
26
static int work_tree_config_is_bogus;
27
enum allowed_bare_repo {
28
  ALLOWED_BARE_REPO_EXPLICIT = 0,
29
  ALLOWED_BARE_REPO_ALL,
30
};
31
32
static struct startup_info the_startup_info;
33
struct startup_info *startup_info = &the_startup_info;
34
const char *tmp_original_cwd;
35
36
/*
37
 * The input parameter must contain an absolute path, and it must already be
38
 * normalized.
39
 *
40
 * Find the part of an absolute path that lies inside the work tree by
41
 * dereferencing symlinks outside the work tree, for example:
42
 * /dir1/repo/dir2/file   (work tree is /dir1/repo)      -> dir2/file
43
 * /dir/file              (work tree is /)               -> dir/file
44
 * /dir/symlink1/symlink2 (symlink1 points to work tree) -> symlink2
45
 * /dir/repolink/file     (repolink points to /dir/repo) -> file
46
 * /dir/repo              (exactly equal to work tree)   -> (empty string)
47
 */
48
static int abspath_part_inside_repo(char *path)
49
0
{
50
0
  size_t len;
51
0
  size_t wtlen;
52
0
  char *path0;
53
0
  int off;
54
0
  const char *work_tree = precompose_string_if_needed(get_git_work_tree());
55
0
  struct strbuf realpath = STRBUF_INIT;
56
57
0
  if (!work_tree)
58
0
    return -1;
59
0
  wtlen = strlen(work_tree);
60
0
  len = strlen(path);
61
0
  off = offset_1st_component(path);
62
63
  /* check if work tree is already the prefix */
64
0
  if (wtlen <= len && !fspathncmp(path, work_tree, wtlen)) {
65
0
    if (path[wtlen] == '/') {
66
0
      memmove(path, path + wtlen + 1, len - wtlen);
67
0
      return 0;
68
0
    } else if (path[wtlen - 1] == '/' || path[wtlen] == '\0') {
69
      /* work tree is the root, or the whole path */
70
0
      memmove(path, path + wtlen, len - wtlen + 1);
71
0
      return 0;
72
0
    }
73
    /* work tree might match beginning of a symlink to work tree */
74
0
    off = wtlen;
75
0
  }
76
0
  path0 = path;
77
0
  path += off;
78
79
  /* check each '/'-terminated level */
80
0
  while (*path) {
81
0
    path++;
82
0
    if (*path == '/') {
83
0
      *path = '\0';
84
0
      strbuf_realpath(&realpath, path0, 1);
85
0
      if (fspathcmp(realpath.buf, work_tree) == 0) {
86
0
        memmove(path0, path + 1, len - (path - path0));
87
0
        strbuf_release(&realpath);
88
0
        return 0;
89
0
      }
90
0
      *path = '/';
91
0
    }
92
0
  }
93
94
  /* check whole path */
95
0
  strbuf_realpath(&realpath, path0, 1);
96
0
  if (fspathcmp(realpath.buf, work_tree) == 0) {
97
0
    *path0 = '\0';
98
0
    strbuf_release(&realpath);
99
0
    return 0;
100
0
  }
101
102
0
  strbuf_release(&realpath);
103
0
  return -1;
104
0
}
105
106
/*
107
 * Normalize "path", prepending the "prefix" for relative paths. If
108
 * remaining_prefix is not NULL, return the actual prefix still
109
 * remains in the path. For example, prefix = sub1/sub2/ and path is
110
 *
111
 *  foo          -> sub1/sub2/foo  (full prefix)
112
 *  ../foo       -> sub1/foo       (remaining prefix is sub1/)
113
 *  ../../bar    -> bar            (no remaining prefix)
114
 *  ../../sub1/sub2/foo -> sub1/sub2/foo (but no remaining prefix)
115
 *  `pwd`/../bar -> sub1/bar       (no remaining prefix)
116
 */
117
char *prefix_path_gently(const char *prefix, int len,
118
       int *remaining_prefix, const char *path)
119
0
{
120
0
  const char *orig = path;
121
0
  char *sanitized;
122
0
  if (is_absolute_path(orig)) {
123
0
    sanitized = xmallocz(strlen(path));
124
0
    if (remaining_prefix)
125
0
      *remaining_prefix = 0;
126
0
    if (normalize_path_copy_len(sanitized, path, remaining_prefix)) {
127
0
      free(sanitized);
128
0
      return NULL;
129
0
    }
130
0
    if (abspath_part_inside_repo(sanitized)) {
131
0
      free(sanitized);
132
0
      return NULL;
133
0
    }
134
0
  } else {
135
0
    sanitized = xstrfmt("%.*s%s", len, len ? prefix : "", path);
136
0
    if (remaining_prefix)
137
0
      *remaining_prefix = len;
138
0
    if (normalize_path_copy_len(sanitized, sanitized, remaining_prefix)) {
139
0
      free(sanitized);
140
0
      return NULL;
141
0
    }
142
0
  }
143
0
  return sanitized;
144
0
}
145
146
char *prefix_path(const char *prefix, int len, const char *path)
147
0
{
148
0
  char *r = prefix_path_gently(prefix, len, NULL, path);
149
0
  if (!r) {
150
0
    const char *hint_path = get_git_work_tree();
151
0
    if (!hint_path)
152
0
      hint_path = get_git_dir();
153
0
    die(_("'%s' is outside repository at '%s'"), path,
154
0
        absolute_path(hint_path));
155
0
  }
156
0
  return r;
157
0
}
158
159
int path_inside_repo(const char *prefix, const char *path)
160
0
{
161
0
  int len = prefix ? strlen(prefix) : 0;
162
0
  char *r = prefix_path_gently(prefix, len, NULL, path);
163
0
  if (r) {
164
0
    free(r);
165
0
    return 1;
166
0
  }
167
0
  return 0;
168
0
}
169
170
int check_filename(const char *prefix, const char *arg)
171
0
{
172
0
  char *to_free = NULL;
173
0
  struct stat st;
174
175
0
  if (skip_prefix(arg, ":/", &arg)) {
176
0
    if (!*arg) /* ":/" is root dir, always exists */
177
0
      return 1;
178
0
    prefix = NULL;
179
0
  } else if (skip_prefix(arg, ":!", &arg) ||
180
0
       skip_prefix(arg, ":^", &arg)) {
181
0
    if (!*arg) /* excluding everything is silly, but allowed */
182
0
      return 1;
183
0
  }
184
185
0
  if (prefix)
186
0
    arg = to_free = prefix_filename(prefix, arg);
187
188
0
  if (!lstat(arg, &st)) {
189
0
    free(to_free);
190
0
    return 1; /* file exists */
191
0
  }
192
0
  if (is_missing_file_error(errno)) {
193
0
    free(to_free);
194
0
    return 0; /* file does not exist */
195
0
  }
196
0
  die_errno(_("failed to stat '%s'"), arg);
197
0
}
198
199
static void NORETURN die_verify_filename(struct repository *r,
200
           const char *prefix,
201
           const char *arg,
202
           int diagnose_misspelt_rev)
203
0
{
204
0
  if (!diagnose_misspelt_rev)
205
0
    die(_("%s: no such path in the working tree.\n"
206
0
          "Use 'git <command> -- <path>...' to specify paths that do not exist locally."),
207
0
        arg);
208
  /*
209
   * Saying "'(icase)foo' does not exist in the index" when the
210
   * user gave us ":(icase)foo" is just stupid.  A magic pathspec
211
   * begins with a colon and is followed by a non-alnum; do not
212
   * let maybe_die_on_misspelt_object_name() even trigger.
213
   */
214
0
  if (!(arg[0] == ':' && !isalnum(arg[1])))
215
0
    maybe_die_on_misspelt_object_name(r, arg, prefix);
216
217
  /* ... or fall back the most general message. */
218
0
  die(_("ambiguous argument '%s': unknown revision or path not in the working tree.\n"
219
0
        "Use '--' to separate paths from revisions, like this:\n"
220
0
        "'git <command> [<revision>...] -- [<file>...]'"), arg);
221
222
0
}
223
224
/*
225
 * Check for arguments that don't resolve as actual files,
226
 * but which look sufficiently like pathspecs that we'll consider
227
 * them such for the purposes of rev/pathspec DWIM parsing.
228
 */
229
static int looks_like_pathspec(const char *arg)
230
0
{
231
0
  const char *p;
232
0
  int escaped = 0;
233
234
  /*
235
   * Wildcard characters imply the user is looking to match pathspecs
236
   * that aren't in the filesystem. Note that this doesn't include
237
   * backslash even though it's a glob special; by itself it doesn't
238
   * cause any increase in the match. Likewise ignore backslash-escaped
239
   * wildcard characters.
240
   */
241
0
  for (p = arg; *p; p++) {
242
0
    if (escaped) {
243
0
      escaped = 0;
244
0
    } else if (is_glob_special(*p)) {
245
0
      if (*p == '\\')
246
0
        escaped = 1;
247
0
      else
248
0
        return 1;
249
0
    }
250
0
  }
251
252
  /* long-form pathspec magic */
253
0
  if (starts_with(arg, ":("))
254
0
    return 1;
255
256
0
  return 0;
257
0
}
258
259
/*
260
 * Verify a filename that we got as an argument for a pathspec
261
 * entry. Note that a filename that begins with "-" never verifies
262
 * as true, because even if such a filename were to exist, we want
263
 * it to be preceded by the "--" marker (or we want the user to
264
 * use a format like "./-filename")
265
 *
266
 * The "diagnose_misspelt_rev" is used to provide a user-friendly
267
 * diagnosis when dying upon finding that "name" is not a pathname.
268
 * If set to 1, the diagnosis will try to diagnose "name" as an
269
 * invalid object name (e.g. HEAD:foo). If set to 0, the diagnosis
270
 * will only complain about an inexisting file.
271
 *
272
 * This function is typically called to check that a "file or rev"
273
 * argument is unambiguous. In this case, the caller will want
274
 * diagnose_misspelt_rev == 1 when verifying the first non-rev
275
 * argument (which could have been a revision), and
276
 * diagnose_misspelt_rev == 0 for the next ones (because we already
277
 * saw a filename, there's not ambiguity anymore).
278
 */
279
void verify_filename(const char *prefix,
280
         const char *arg,
281
         int diagnose_misspelt_rev)
282
0
{
283
0
  if (*arg == '-')
284
0
    die(_("option '%s' must come before non-option arguments"), arg);
285
0
  if (looks_like_pathspec(arg) || check_filename(prefix, arg))
286
0
    return;
287
0
  die_verify_filename(the_repository, prefix, arg, diagnose_misspelt_rev);
288
0
}
289
290
/*
291
 * Opposite of the above: the command line did not have -- marker
292
 * and we parsed the arg as a refname.  It should not be interpretable
293
 * as a filename.
294
 */
295
void verify_non_filename(const char *prefix, const char *arg)
296
0
{
297
0
  if (!is_inside_work_tree() || is_inside_git_dir())
298
0
    return;
299
0
  if (*arg == '-')
300
0
    return; /* flag */
301
0
  if (!check_filename(prefix, arg))
302
0
    return;
303
0
  die(_("ambiguous argument '%s': both revision and filename\n"
304
0
        "Use '--' to separate paths from revisions, like this:\n"
305
0
        "'git <command> [<revision>...] -- [<file>...]'"), arg);
306
0
}
307
308
int get_common_dir(struct strbuf *sb, const char *gitdir)
309
0
{
310
0
  const char *git_env_common_dir = getenv(GIT_COMMON_DIR_ENVIRONMENT);
311
0
  if (git_env_common_dir) {
312
0
    strbuf_addstr(sb, git_env_common_dir);
313
0
    return 1;
314
0
  } else {
315
0
    return get_common_dir_noenv(sb, gitdir);
316
0
  }
317
0
}
318
319
int get_common_dir_noenv(struct strbuf *sb, const char *gitdir)
320
0
{
321
0
  struct strbuf data = STRBUF_INIT;
322
0
  struct strbuf path = STRBUF_INIT;
323
0
  int ret = 0;
324
325
0
  strbuf_addf(&path, "%s/commondir", gitdir);
326
0
  if (file_exists(path.buf)) {
327
0
    if (strbuf_read_file(&data, path.buf, 0) <= 0)
328
0
      die_errno(_("failed to read %s"), path.buf);
329
0
    while (data.len && (data.buf[data.len - 1] == '\n' ||
330
0
            data.buf[data.len - 1] == '\r'))
331
0
      data.len--;
332
0
    data.buf[data.len] = '\0';
333
0
    strbuf_reset(&path);
334
0
    if (!is_absolute_path(data.buf))
335
0
      strbuf_addf(&path, "%s/", gitdir);
336
0
    strbuf_addbuf(&path, &data);
337
0
    strbuf_add_real_path(sb, path.buf);
338
0
    ret = 1;
339
0
  } else {
340
0
    strbuf_addstr(sb, gitdir);
341
0
  }
342
343
0
  strbuf_release(&data);
344
0
  strbuf_release(&path);
345
0
  return ret;
346
0
}
347
348
static int validate_headref(const char *path)
349
0
{
350
0
  struct stat st;
351
0
  char buffer[256];
352
0
  const char *refname;
353
0
  struct object_id oid;
354
0
  int fd;
355
0
  ssize_t len;
356
357
0
  if (lstat(path, &st) < 0)
358
0
    return -1;
359
360
  /* Make sure it is a "refs/.." symlink */
361
0
  if (S_ISLNK(st.st_mode)) {
362
0
    len = readlink(path, buffer, sizeof(buffer)-1);
363
0
    if (len >= 5 && !memcmp("refs/", buffer, 5))
364
0
      return 0;
365
0
    return -1;
366
0
  }
367
368
  /*
369
   * Anything else, just open it and try to see if it is a symbolic ref.
370
   */
371
0
  fd = open(path, O_RDONLY);
372
0
  if (fd < 0)
373
0
    return -1;
374
0
  len = read_in_full(fd, buffer, sizeof(buffer)-1);
375
0
  close(fd);
376
377
0
  if (len < 0)
378
0
    return -1;
379
0
  buffer[len] = '\0';
380
381
  /*
382
   * Is it a symbolic ref?
383
   */
384
0
  if (skip_prefix(buffer, "ref:", &refname)) {
385
0
    while (isspace(*refname))
386
0
      refname++;
387
0
    if (starts_with(refname, "refs/"))
388
0
      return 0;
389
0
  }
390
391
  /*
392
   * Is this a detached HEAD?
393
   */
394
0
  if (get_oid_hex_any(buffer, &oid) != GIT_HASH_UNKNOWN)
395
0
    return 0;
396
397
0
  return -1;
398
0
}
399
400
/*
401
 * Test if it looks like we're at a git directory.
402
 * We want to see:
403
 *
404
 *  - either an objects/ directory _or_ the proper
405
 *    GIT_OBJECT_DIRECTORY environment variable
406
 *  - a refs/ directory
407
 *  - either a HEAD symlink or a HEAD file that is formatted as
408
 *    a proper "ref:", or a regular file HEAD that has a properly
409
 *    formatted sha1 object name.
410
 */
411
int is_git_directory(const char *suspect)
412
0
{
413
0
  struct strbuf path = STRBUF_INIT;
414
0
  int ret = 0;
415
0
  size_t len;
416
417
  /* Check worktree-related signatures */
418
0
  strbuf_addstr(&path, suspect);
419
0
  strbuf_complete(&path, '/');
420
0
  strbuf_addstr(&path, "HEAD");
421
0
  if (validate_headref(path.buf))
422
0
    goto done;
423
424
0
  strbuf_reset(&path);
425
0
  get_common_dir(&path, suspect);
426
0
  len = path.len;
427
428
  /* Check non-worktree-related signatures */
429
0
  if (getenv(DB_ENVIRONMENT)) {
430
0
    if (access(getenv(DB_ENVIRONMENT), X_OK))
431
0
      goto done;
432
0
  }
433
0
  else {
434
0
    strbuf_setlen(&path, len);
435
0
    strbuf_addstr(&path, "/objects");
436
0
    if (access(path.buf, X_OK))
437
0
      goto done;
438
0
  }
439
440
0
  strbuf_setlen(&path, len);
441
0
  strbuf_addstr(&path, "/refs");
442
0
  if (access(path.buf, X_OK))
443
0
    goto done;
444
445
0
  ret = 1;
446
0
done:
447
0
  strbuf_release(&path);
448
0
  return ret;
449
0
}
450
451
int is_nonbare_repository_dir(struct strbuf *path)
452
0
{
453
0
  int ret = 0;
454
0
  int gitfile_error;
455
0
  size_t orig_path_len = path->len;
456
0
  assert(orig_path_len != 0);
457
0
  strbuf_complete(path, '/');
458
0
  strbuf_addstr(path, ".git");
459
0
  if (read_gitfile_gently(path->buf, &gitfile_error) || is_git_directory(path->buf))
460
0
    ret = 1;
461
0
  if (gitfile_error == READ_GITFILE_ERR_OPEN_FAILED ||
462
0
      gitfile_error == READ_GITFILE_ERR_READ_FAILED)
463
0
    ret = 1;
464
0
  strbuf_setlen(path, orig_path_len);
465
0
  return ret;
466
0
}
467
468
int is_inside_git_dir(void)
469
0
{
470
0
  if (inside_git_dir < 0)
471
0
    inside_git_dir = is_inside_dir(get_git_dir());
472
0
  return inside_git_dir;
473
0
}
474
475
int is_inside_work_tree(void)
476
0
{
477
0
  if (inside_work_tree < 0)
478
0
    inside_work_tree = is_inside_dir(get_git_work_tree());
479
0
  return inside_work_tree;
480
0
}
481
482
void setup_work_tree(void)
483
0
{
484
0
  const char *work_tree;
485
0
  static int initialized = 0;
486
487
0
  if (initialized)
488
0
    return;
489
490
0
  if (work_tree_config_is_bogus)
491
0
    die(_("unable to set up work tree using invalid config"));
492
493
0
  work_tree = get_git_work_tree();
494
0
  if (!work_tree || chdir_notify(work_tree))
495
0
    die(_("this operation must be run in a work tree"));
496
497
  /*
498
   * Make sure subsequent git processes find correct worktree
499
   * if $GIT_WORK_TREE is set relative
500
   */
501
0
  if (getenv(GIT_WORK_TREE_ENVIRONMENT))
502
0
    setenv(GIT_WORK_TREE_ENVIRONMENT, ".", 1);
503
504
0
  initialized = 1;
505
0
}
506
507
static void setup_original_cwd(void)
508
0
{
509
0
  struct strbuf tmp = STRBUF_INIT;
510
0
  const char *worktree = NULL;
511
0
  int offset = -1;
512
513
0
  if (!tmp_original_cwd)
514
0
    return;
515
516
  /*
517
   * startup_info->original_cwd points to the current working
518
   * directory we inherited from our parent process, which is a
519
   * directory we want to avoid removing.
520
   *
521
   * For convience, we would like to have the path relative to the
522
   * worktree instead of an absolute path.
523
   *
524
   * Yes, startup_info->original_cwd is usually the same as 'prefix',
525
   * but differs in two ways:
526
   *   - prefix has a trailing '/'
527
   *   - if the user passes '-C' to git, that modifies the prefix but
528
   *     not startup_info->original_cwd.
529
   */
530
531
  /* Normalize the directory */
532
0
  if (!strbuf_realpath(&tmp, tmp_original_cwd, 0)) {
533
0
    trace2_data_string("setup", the_repository,
534
0
           "realpath-path", tmp_original_cwd);
535
0
    trace2_data_string("setup", the_repository,
536
0
           "realpath-failure", strerror(errno));
537
0
    free((char*)tmp_original_cwd);
538
0
    tmp_original_cwd = NULL;
539
0
    return;
540
0
  }
541
542
0
  free((char*)tmp_original_cwd);
543
0
  tmp_original_cwd = NULL;
544
0
  startup_info->original_cwd = strbuf_detach(&tmp, NULL);
545
546
  /*
547
   * Get our worktree; we only protect the current working directory
548
   * if it's in the worktree.
549
   */
550
0
  worktree = get_git_work_tree();
551
0
  if (!worktree)
552
0
    goto no_prevention_needed;
553
554
0
  offset = dir_inside_of(startup_info->original_cwd, worktree);
555
0
  if (offset >= 0) {
556
    /*
557
     * If startup_info->original_cwd == worktree, that is already
558
     * protected and we don't need original_cwd as a secondary
559
     * protection measure.
560
     */
561
0
    if (!*(startup_info->original_cwd + offset))
562
0
      goto no_prevention_needed;
563
564
    /*
565
     * original_cwd was inside worktree; precompose it just as
566
     * we do prefix so that built up paths will match
567
     */
568
0
    startup_info->original_cwd = \
569
0
      precompose_string_if_needed(startup_info->original_cwd
570
0
                + offset);
571
0
    return;
572
0
  }
573
574
0
no_prevention_needed:
575
0
  free((char*)startup_info->original_cwd);
576
0
  startup_info->original_cwd = NULL;
577
0
}
578
579
static int read_worktree_config(const char *var, const char *value,
580
        const struct config_context *ctx UNUSED,
581
        void *vdata)
582
0
{
583
0
  struct repository_format *data = vdata;
584
585
0
  if (strcmp(var, "core.bare") == 0) {
586
0
    data->is_bare = git_config_bool(var, value);
587
0
  } else if (strcmp(var, "core.worktree") == 0) {
588
0
    if (!value)
589
0
      return config_error_nonbool(var);
590
0
    free(data->work_tree);
591
0
    data->work_tree = xstrdup(value);
592
0
  }
593
0
  return 0;
594
0
}
595
596
enum extension_result {
597
  EXTENSION_ERROR = -1, /* compatible with error(), etc */
598
  EXTENSION_UNKNOWN = 0,
599
  EXTENSION_OK = 1
600
};
601
602
/*
603
 * Do not add new extensions to this function. It handles extensions which are
604
 * respected even in v0-format repositories for historical compatibility.
605
 */
606
static enum extension_result handle_extension_v0(const char *var,
607
             const char *value,
608
             const char *ext,
609
             struct repository_format *data)
610
0
{
611
0
    if (!strcmp(ext, "noop")) {
612
0
      return EXTENSION_OK;
613
0
    } else if (!strcmp(ext, "preciousobjects")) {
614
0
      data->precious_objects = git_config_bool(var, value);
615
0
      return EXTENSION_OK;
616
0
    } else if (!strcmp(ext, "partialclone")) {
617
0
      if (!value)
618
0
        return config_error_nonbool(var);
619
0
      data->partial_clone = xstrdup(value);
620
0
      return EXTENSION_OK;
621
0
    } else if (!strcmp(ext, "worktreeconfig")) {
622
0
      data->worktree_config = git_config_bool(var, value);
623
0
      return EXTENSION_OK;
624
0
    }
625
626
0
    return EXTENSION_UNKNOWN;
627
0
}
628
629
/*
630
 * Record any new extensions in this function.
631
 */
632
static enum extension_result handle_extension(const char *var,
633
                const char *value,
634
                const char *ext,
635
                struct repository_format *data)
636
0
{
637
0
  if (!strcmp(ext, "noop-v1")) {
638
0
    return EXTENSION_OK;
639
0
  } else if (!strcmp(ext, "objectformat")) {
640
0
    int format;
641
642
0
    if (!value)
643
0
      return config_error_nonbool(var);
644
0
    format = hash_algo_by_name(value);
645
0
    if (format == GIT_HASH_UNKNOWN)
646
0
      return error(_("invalid value for '%s': '%s'"),
647
0
             "extensions.objectformat", value);
648
0
    data->hash_algo = format;
649
0
    return EXTENSION_OK;
650
0
  } else if (!strcmp(ext, "compatobjectformat")) {
651
0
    struct string_list_item *item;
652
0
    int format;
653
654
0
    if (!value)
655
0
      return config_error_nonbool(var);
656
0
    format = hash_algo_by_name(value);
657
0
    if (format == GIT_HASH_UNKNOWN)
658
0
      return error(_("invalid value for '%s': '%s'"),
659
0
             "extensions.compatobjectformat", value);
660
    /* For now only support compatObjectFormat being specified once. */
661
0
    for_each_string_list_item(item, &data->v1_only_extensions) {
662
0
      if (!strcmp(item->string, "compatobjectformat"))
663
0
        return error(_("'%s' already specified as '%s'"),
664
0
          "extensions.compatobjectformat",
665
0
          hash_algos[data->compat_hash_algo].name);
666
0
    }
667
0
    data->compat_hash_algo = format;
668
0
    return EXTENSION_OK;
669
0
  } else if (!strcmp(ext, "refstorage")) {
670
0
    unsigned int format;
671
672
0
    if (!value)
673
0
      return config_error_nonbool(var);
674
0
    format = ref_storage_format_by_name(value);
675
0
    if (format == REF_STORAGE_FORMAT_UNKNOWN)
676
0
      return error(_("invalid value for '%s': '%s'"),
677
0
             "extensions.refstorage", value);
678
0
    data->ref_storage_format = format;
679
0
    return EXTENSION_OK;
680
0
  }
681
0
  return EXTENSION_UNKNOWN;
682
0
}
683
684
static int check_repo_format(const char *var, const char *value,
685
           const struct config_context *ctx, void *vdata)
686
0
{
687
0
  struct repository_format *data = vdata;
688
0
  const char *ext;
689
690
0
  if (strcmp(var, "core.repositoryformatversion") == 0)
691
0
    data->version = git_config_int(var, value, ctx->kvi);
692
0
  else if (skip_prefix(var, "extensions.", &ext)) {
693
0
    switch (handle_extension_v0(var, value, ext, data)) {
694
0
    case EXTENSION_ERROR:
695
0
      return -1;
696
0
    case EXTENSION_OK:
697
0
      return 0;
698
0
    case EXTENSION_UNKNOWN:
699
0
      break;
700
0
    }
701
702
0
    switch (handle_extension(var, value, ext, data)) {
703
0
    case EXTENSION_ERROR:
704
0
      return -1;
705
0
    case EXTENSION_OK:
706
0
      string_list_append(&data->v1_only_extensions, ext);
707
0
      return 0;
708
0
    case EXTENSION_UNKNOWN:
709
0
      string_list_append(&data->unknown_extensions, ext);
710
0
      return 0;
711
0
    }
712
0
  }
713
714
0
  return read_worktree_config(var, value, ctx, vdata);
715
0
}
716
717
static int check_repository_format_gently(const char *gitdir, struct repository_format *candidate, int *nongit_ok)
718
0
{
719
0
  struct strbuf sb = STRBUF_INIT;
720
0
  struct strbuf err = STRBUF_INIT;
721
0
  int has_common;
722
723
0
  has_common = get_common_dir(&sb, gitdir);
724
0
  strbuf_addstr(&sb, "/config");
725
0
  read_repository_format(candidate, sb.buf);
726
0
  strbuf_release(&sb);
727
728
  /*
729
   * For historical use of check_repository_format() in git-init,
730
   * we treat a missing config as a silent "ok", even when nongit_ok
731
   * is unset.
732
   */
733
0
  if (candidate->version < 0)
734
0
    return 0;
735
736
0
  if (verify_repository_format(candidate, &err) < 0) {
737
0
    if (nongit_ok) {
738
0
      warning("%s", err.buf);
739
0
      strbuf_release(&err);
740
0
      *nongit_ok = -1;
741
0
      return -1;
742
0
    }
743
0
    die("%s", err.buf);
744
0
  }
745
746
0
  repository_format_precious_objects = candidate->precious_objects;
747
0
  string_list_clear(&candidate->unknown_extensions, 0);
748
0
  string_list_clear(&candidate->v1_only_extensions, 0);
749
750
0
  if (candidate->worktree_config) {
751
    /*
752
     * pick up core.bare and core.worktree from per-worktree
753
     * config if present
754
     */
755
0
    strbuf_addf(&sb, "%s/config.worktree", gitdir);
756
0
    git_config_from_file(read_worktree_config, sb.buf, candidate);
757
0
    strbuf_release(&sb);
758
0
    has_common = 0;
759
0
  }
760
761
0
  if (!has_common) {
762
0
    if (candidate->is_bare != -1) {
763
0
      is_bare_repository_cfg = candidate->is_bare;
764
0
      if (is_bare_repository_cfg == 1)
765
0
        inside_work_tree = -1;
766
0
    }
767
0
    if (candidate->work_tree) {
768
0
      free(git_work_tree_cfg);
769
0
      git_work_tree_cfg = xstrdup(candidate->work_tree);
770
0
      inside_work_tree = -1;
771
0
    }
772
0
  }
773
774
0
  return 0;
775
0
}
776
777
int upgrade_repository_format(int target_version)
778
0
{
779
0
  struct strbuf sb = STRBUF_INIT;
780
0
  struct strbuf err = STRBUF_INIT;
781
0
  struct strbuf repo_version = STRBUF_INIT;
782
0
  struct repository_format repo_fmt = REPOSITORY_FORMAT_INIT;
783
0
  int ret;
784
785
0
  strbuf_git_common_path(&sb, the_repository, "config");
786
0
  read_repository_format(&repo_fmt, sb.buf);
787
0
  strbuf_release(&sb);
788
789
0
  if (repo_fmt.version >= target_version) {
790
0
    ret = 0;
791
0
    goto out;
792
0
  }
793
794
0
  if (verify_repository_format(&repo_fmt, &err) < 0) {
795
0
    ret = error("cannot upgrade repository format from %d to %d: %s",
796
0
          repo_fmt.version, target_version, err.buf);
797
0
    goto out;
798
0
  }
799
0
  if (!repo_fmt.version && repo_fmt.unknown_extensions.nr) {
800
0
    ret = error("cannot upgrade repository format: "
801
0
          "unknown extension %s",
802
0
          repo_fmt.unknown_extensions.items[0].string);
803
0
    goto out;
804
0
  }
805
806
0
  strbuf_addf(&repo_version, "%d", target_version);
807
0
  git_config_set("core.repositoryformatversion", repo_version.buf);
808
809
0
  ret = 1;
810
811
0
out:
812
0
  clear_repository_format(&repo_fmt);
813
0
  strbuf_release(&repo_version);
814
0
  strbuf_release(&err);
815
0
  return ret;
816
0
}
817
818
static void init_repository_format(struct repository_format *format)
819
0
{
820
0
  const struct repository_format fresh = REPOSITORY_FORMAT_INIT;
821
822
0
  memcpy(format, &fresh, sizeof(fresh));
823
0
}
824
825
int read_repository_format(struct repository_format *format, const char *path)
826
0
{
827
0
  clear_repository_format(format);
828
0
  git_config_from_file(check_repo_format, path, format);
829
0
  if (format->version == -1)
830
0
    clear_repository_format(format);
831
0
  return format->version;
832
0
}
833
834
void clear_repository_format(struct repository_format *format)
835
0
{
836
0
  string_list_clear(&format->unknown_extensions, 0);
837
0
  string_list_clear(&format->v1_only_extensions, 0);
838
0
  free(format->work_tree);
839
0
  free(format->partial_clone);
840
0
  init_repository_format(format);
841
0
}
842
843
int verify_repository_format(const struct repository_format *format,
844
           struct strbuf *err)
845
0
{
846
0
  if (GIT_REPO_VERSION_READ < format->version) {
847
0
    strbuf_addf(err, _("Expected git repo version <= %d, found %d"),
848
0
          GIT_REPO_VERSION_READ, format->version);
849
0
    return -1;
850
0
  }
851
852
0
  if (format->version >= 1 && format->unknown_extensions.nr) {
853
0
    int i;
854
855
0
    strbuf_addstr(err, Q_("unknown repository extension found:",
856
0
              "unknown repository extensions found:",
857
0
              format->unknown_extensions.nr));
858
859
0
    for (i = 0; i < format->unknown_extensions.nr; i++)
860
0
      strbuf_addf(err, "\n\t%s",
861
0
            format->unknown_extensions.items[i].string);
862
0
    return -1;
863
0
  }
864
865
0
  if (format->version == 0 && format->v1_only_extensions.nr) {
866
0
    int i;
867
868
0
    strbuf_addstr(err,
869
0
            Q_("repo version is 0, but v1-only extension found:",
870
0
         "repo version is 0, but v1-only extensions found:",
871
0
         format->v1_only_extensions.nr));
872
873
0
    for (i = 0; i < format->v1_only_extensions.nr; i++)
874
0
      strbuf_addf(err, "\n\t%s",
875
0
            format->v1_only_extensions.items[i].string);
876
0
    return -1;
877
0
  }
878
879
0
  return 0;
880
0
}
881
882
void read_gitfile_error_die(int error_code, const char *path, const char *dir)
883
0
{
884
0
  switch (error_code) {
885
0
  case READ_GITFILE_ERR_STAT_FAILED:
886
0
  case READ_GITFILE_ERR_NOT_A_FILE:
887
    /* non-fatal; follow return path */
888
0
    break;
889
0
  case READ_GITFILE_ERR_OPEN_FAILED:
890
0
    die_errno(_("error opening '%s'"), path);
891
0
  case READ_GITFILE_ERR_TOO_LARGE:
892
0
    die(_("too large to be a .git file: '%s'"), path);
893
0
  case READ_GITFILE_ERR_READ_FAILED:
894
0
    die(_("error reading %s"), path);
895
0
  case READ_GITFILE_ERR_INVALID_FORMAT:
896
0
    die(_("invalid gitfile format: %s"), path);
897
0
  case READ_GITFILE_ERR_NO_PATH:
898
0
    die(_("no path in gitfile: %s"), path);
899
0
  case READ_GITFILE_ERR_NOT_A_REPO:
900
0
    die(_("not a git repository: %s"), dir);
901
0
  default:
902
0
    BUG("unknown error code");
903
0
  }
904
0
}
905
906
/*
907
 * Try to read the location of the git directory from the .git file,
908
 * return path to git directory if found. The return value comes from
909
 * a shared buffer.
910
 *
911
 * On failure, if return_error_code is not NULL, return_error_code
912
 * will be set to an error code and NULL will be returned. If
913
 * return_error_code is NULL the function will die instead (for most
914
 * cases).
915
 */
916
const char *read_gitfile_gently(const char *path, int *return_error_code)
917
0
{
918
0
  const int max_file_size = 1 << 20;  /* 1MB */
919
0
  int error_code = 0;
920
0
  char *buf = NULL;
921
0
  char *dir = NULL;
922
0
  const char *slash;
923
0
  struct stat st;
924
0
  int fd;
925
0
  ssize_t len;
926
0
  static struct strbuf realpath = STRBUF_INIT;
927
928
0
  if (stat(path, &st)) {
929
    /* NEEDSWORK: discern between ENOENT vs other errors */
930
0
    error_code = READ_GITFILE_ERR_STAT_FAILED;
931
0
    goto cleanup_return;
932
0
  }
933
0
  if (!S_ISREG(st.st_mode)) {
934
0
    error_code = READ_GITFILE_ERR_NOT_A_FILE;
935
0
    goto cleanup_return;
936
0
  }
937
0
  if (st.st_size > max_file_size) {
938
0
    error_code = READ_GITFILE_ERR_TOO_LARGE;
939
0
    goto cleanup_return;
940
0
  }
941
0
  fd = open(path, O_RDONLY);
942
0
  if (fd < 0) {
943
0
    error_code = READ_GITFILE_ERR_OPEN_FAILED;
944
0
    goto cleanup_return;
945
0
  }
946
0
  buf = xmallocz(st.st_size);
947
0
  len = read_in_full(fd, buf, st.st_size);
948
0
  close(fd);
949
0
  if (len != st.st_size) {
950
0
    error_code = READ_GITFILE_ERR_READ_FAILED;
951
0
    goto cleanup_return;
952
0
  }
953
0
  if (!starts_with(buf, "gitdir: ")) {
954
0
    error_code = READ_GITFILE_ERR_INVALID_FORMAT;
955
0
    goto cleanup_return;
956
0
  }
957
0
  while (buf[len - 1] == '\n' || buf[len - 1] == '\r')
958
0
    len--;
959
0
  if (len < 9) {
960
0
    error_code = READ_GITFILE_ERR_NO_PATH;
961
0
    goto cleanup_return;
962
0
  }
963
0
  buf[len] = '\0';
964
0
  dir = buf + 8;
965
966
0
  if (!is_absolute_path(dir) && (slash = strrchr(path, '/'))) {
967
0
    size_t pathlen = slash+1 - path;
968
0
    dir = xstrfmt("%.*s%.*s", (int)pathlen, path,
969
0
            (int)(len - 8), buf + 8);
970
0
    free(buf);
971
0
    buf = dir;
972
0
  }
973
0
  if (!is_git_directory(dir)) {
974
0
    error_code = READ_GITFILE_ERR_NOT_A_REPO;
975
0
    goto cleanup_return;
976
0
  }
977
978
0
  strbuf_realpath(&realpath, dir, 1);
979
0
  path = realpath.buf;
980
981
0
cleanup_return:
982
0
  if (return_error_code)
983
0
    *return_error_code = error_code;
984
0
  else if (error_code)
985
0
    read_gitfile_error_die(error_code, path, dir);
986
987
0
  free(buf);
988
0
  return error_code ? NULL : path;
989
0
}
990
991
static const char *setup_explicit_git_dir(const char *gitdirenv,
992
            struct strbuf *cwd,
993
            struct repository_format *repo_fmt,
994
            int *nongit_ok)
995
0
{
996
0
  const char *work_tree_env = getenv(GIT_WORK_TREE_ENVIRONMENT);
997
0
  const char *worktree;
998
0
  char *gitfile;
999
0
  int offset;
1000
1001
0
  if (PATH_MAX - 40 < strlen(gitdirenv))
1002
0
    die(_("'$%s' too big"), GIT_DIR_ENVIRONMENT);
1003
1004
0
  gitfile = (char*)read_gitfile(gitdirenv);
1005
0
  if (gitfile) {
1006
0
    gitfile = xstrdup(gitfile);
1007
0
    gitdirenv = gitfile;
1008
0
  }
1009
1010
0
  if (!is_git_directory(gitdirenv)) {
1011
0
    if (nongit_ok) {
1012
0
      *nongit_ok = 1;
1013
0
      free(gitfile);
1014
0
      return NULL;
1015
0
    }
1016
0
    die(_("not a git repository: '%s'"), gitdirenv);
1017
0
  }
1018
1019
0
  if (check_repository_format_gently(gitdirenv, repo_fmt, nongit_ok)) {
1020
0
    free(gitfile);
1021
0
    return NULL;
1022
0
  }
1023
1024
  /* #3, #7, #11, #15, #19, #23, #27, #31 (see t1510) */
1025
0
  if (work_tree_env)
1026
0
    set_git_work_tree(work_tree_env);
1027
0
  else if (is_bare_repository_cfg > 0) {
1028
0
    if (git_work_tree_cfg) {
1029
      /* #22.2, #30 */
1030
0
      warning("core.bare and core.worktree do not make sense");
1031
0
      work_tree_config_is_bogus = 1;
1032
0
    }
1033
1034
    /* #18, #26 */
1035
0
    set_git_dir(gitdirenv, 0);
1036
0
    free(gitfile);
1037
0
    return NULL;
1038
0
  }
1039
0
  else if (git_work_tree_cfg) { /* #6, #14 */
1040
0
    if (is_absolute_path(git_work_tree_cfg))
1041
0
      set_git_work_tree(git_work_tree_cfg);
1042
0
    else {
1043
0
      char *core_worktree;
1044
0
      if (chdir(gitdirenv))
1045
0
        die_errno(_("cannot chdir to '%s'"), gitdirenv);
1046
0
      if (chdir(git_work_tree_cfg))
1047
0
        die_errno(_("cannot chdir to '%s'"), git_work_tree_cfg);
1048
0
      core_worktree = xgetcwd();
1049
0
      if (chdir(cwd->buf))
1050
0
        die_errno(_("cannot come back to cwd"));
1051
0
      set_git_work_tree(core_worktree);
1052
0
      free(core_worktree);
1053
0
    }
1054
0
  }
1055
0
  else if (!git_env_bool(GIT_IMPLICIT_WORK_TREE_ENVIRONMENT, 1)) {
1056
    /* #16d */
1057
0
    set_git_dir(gitdirenv, 0);
1058
0
    free(gitfile);
1059
0
    return NULL;
1060
0
  }
1061
0
  else /* #2, #10 */
1062
0
    set_git_work_tree(".");
1063
1064
  /* set_git_work_tree() must have been called by now */
1065
0
  worktree = get_git_work_tree();
1066
1067
  /* both get_git_work_tree() and cwd are already normalized */
1068
0
  if (!strcmp(cwd->buf, worktree)) { /* cwd == worktree */
1069
0
    set_git_dir(gitdirenv, 0);
1070
0
    free(gitfile);
1071
0
    return NULL;
1072
0
  }
1073
1074
0
  offset = dir_inside_of(cwd->buf, worktree);
1075
0
  if (offset >= 0) { /* cwd inside worktree? */
1076
0
    set_git_dir(gitdirenv, 1);
1077
0
    if (chdir(worktree))
1078
0
      die_errno(_("cannot chdir to '%s'"), worktree);
1079
0
    strbuf_addch(cwd, '/');
1080
0
    free(gitfile);
1081
0
    return cwd->buf + offset;
1082
0
  }
1083
1084
  /* cwd outside worktree */
1085
0
  set_git_dir(gitdirenv, 0);
1086
0
  free(gitfile);
1087
0
  return NULL;
1088
0
}
1089
1090
static const char *setup_discovered_git_dir(const char *gitdir,
1091
              struct strbuf *cwd, int offset,
1092
              struct repository_format *repo_fmt,
1093
              int *nongit_ok)
1094
0
{
1095
0
  if (check_repository_format_gently(gitdir, repo_fmt, nongit_ok))
1096
0
    return NULL;
1097
1098
  /* --work-tree is set without --git-dir; use discovered one */
1099
0
  if (getenv(GIT_WORK_TREE_ENVIRONMENT) || git_work_tree_cfg) {
1100
0
    char *to_free = NULL;
1101
0
    const char *ret;
1102
1103
0
    if (offset != cwd->len && !is_absolute_path(gitdir))
1104
0
      gitdir = to_free = real_pathdup(gitdir, 1);
1105
0
    if (chdir(cwd->buf))
1106
0
      die_errno(_("cannot come back to cwd"));
1107
0
    ret = setup_explicit_git_dir(gitdir, cwd, repo_fmt, nongit_ok);
1108
0
    free(to_free);
1109
0
    return ret;
1110
0
  }
1111
1112
  /* #16.2, #17.2, #20.2, #21.2, #24, #25, #28, #29 (see t1510) */
1113
0
  if (is_bare_repository_cfg > 0) {
1114
0
    set_git_dir(gitdir, (offset != cwd->len));
1115
0
    if (chdir(cwd->buf))
1116
0
      die_errno(_("cannot come back to cwd"));
1117
0
    return NULL;
1118
0
  }
1119
1120
  /* #0, #1, #5, #8, #9, #12, #13 */
1121
0
  set_git_work_tree(".");
1122
0
  if (strcmp(gitdir, DEFAULT_GIT_DIR_ENVIRONMENT))
1123
0
    set_git_dir(gitdir, 0);
1124
0
  inside_git_dir = 0;
1125
0
  inside_work_tree = 1;
1126
0
  if (offset >= cwd->len)
1127
0
    return NULL;
1128
1129
  /* Make "offset" point past the '/' (already the case for root dirs) */
1130
0
  if (offset != offset_1st_component(cwd->buf))
1131
0
    offset++;
1132
  /* Add a '/' at the end */
1133
0
  strbuf_addch(cwd, '/');
1134
0
  return cwd->buf + offset;
1135
0
}
1136
1137
/* #16.1, #17.1, #20.1, #21.1, #22.1 (see t1510) */
1138
static const char *setup_bare_git_dir(struct strbuf *cwd, int offset,
1139
              struct repository_format *repo_fmt,
1140
              int *nongit_ok)
1141
0
{
1142
0
  int root_len;
1143
1144
0
  if (check_repository_format_gently(".", repo_fmt, nongit_ok))
1145
0
    return NULL;
1146
1147
0
  setenv(GIT_IMPLICIT_WORK_TREE_ENVIRONMENT, "0", 1);
1148
1149
  /* --work-tree is set without --git-dir; use discovered one */
1150
0
  if (getenv(GIT_WORK_TREE_ENVIRONMENT) || git_work_tree_cfg) {
1151
0
    static const char *gitdir;
1152
1153
0
    gitdir = offset == cwd->len ? "." : xmemdupz(cwd->buf, offset);
1154
0
    if (chdir(cwd->buf))
1155
0
      die_errno(_("cannot come back to cwd"));
1156
0
    return setup_explicit_git_dir(gitdir, cwd, repo_fmt, nongit_ok);
1157
0
  }
1158
1159
0
  inside_git_dir = 1;
1160
0
  inside_work_tree = 0;
1161
0
  if (offset != cwd->len) {
1162
0
    if (chdir(cwd->buf))
1163
0
      die_errno(_("cannot come back to cwd"));
1164
0
    root_len = offset_1st_component(cwd->buf);
1165
0
    strbuf_setlen(cwd, offset > root_len ? offset : root_len);
1166
0
    set_git_dir(cwd->buf, 0);
1167
0
  }
1168
0
  else
1169
0
    set_git_dir(".", 0);
1170
0
  return NULL;
1171
0
}
1172
1173
static dev_t get_device_or_die(const char *path, const char *prefix, int prefix_len)
1174
0
{
1175
0
  struct stat buf;
1176
0
  if (stat(path, &buf)) {
1177
0
    die_errno(_("failed to stat '%*s%s%s'"),
1178
0
        prefix_len,
1179
0
        prefix ? prefix : "",
1180
0
        prefix ? "/" : "", path);
1181
0
  }
1182
0
  return buf.st_dev;
1183
0
}
1184
1185
/*
1186
 * A "string_list_each_func_t" function that canonicalizes an entry
1187
 * from GIT_CEILING_DIRECTORIES using real_pathdup(), or
1188
 * discards it if unusable.  The presence of an empty entry in
1189
 * GIT_CEILING_DIRECTORIES turns off canonicalization for all
1190
 * subsequent entries.
1191
 */
1192
static int canonicalize_ceiling_entry(struct string_list_item *item,
1193
              void *cb_data)
1194
0
{
1195
0
  int *empty_entry_found = cb_data;
1196
0
  char *ceil = item->string;
1197
1198
0
  if (!*ceil) {
1199
0
    *empty_entry_found = 1;
1200
0
    return 0;
1201
0
  } else if (!is_absolute_path(ceil)) {
1202
0
    return 0;
1203
0
  } else if (*empty_entry_found) {
1204
    /* Keep entry but do not canonicalize it */
1205
0
    return 1;
1206
0
  } else {
1207
0
    char *real_path = real_pathdup(ceil, 0);
1208
0
    if (!real_path) {
1209
0
      return 0;
1210
0
    }
1211
0
    free(item->string);
1212
0
    item->string = real_path;
1213
0
    return 1;
1214
0
  }
1215
0
}
1216
1217
struct safe_directory_data {
1218
  char *path;
1219
  int is_safe;
1220
};
1221
1222
static int safe_directory_cb(const char *key, const char *value,
1223
           const struct config_context *ctx UNUSED, void *d)
1224
0
{
1225
0
  struct safe_directory_data *data = d;
1226
1227
0
  if (strcmp(key, "safe.directory"))
1228
0
    return 0;
1229
1230
0
  if (!value || !*value) {
1231
0
    data->is_safe = 0;
1232
0
  } else if (!strcmp(value, "*")) {
1233
0
    data->is_safe = 1;
1234
0
  } else {
1235
0
    char *allowed = NULL;
1236
1237
0
    if (!git_config_pathname(&allowed, key, value)) {
1238
0
      char *normalized = NULL;
1239
1240
      /*
1241
       * Setting safe.directory to a non-absolute path
1242
       * makes little sense---it won't be relative to
1243
       * the configuration file the item is defined in.
1244
       * Except for ".", which means "if we are at the top
1245
       * level of a repository, then it is OK", which is
1246
       * slightly tighter than "*" that allows discovery.
1247
       */
1248
0
      if (!is_absolute_path(allowed) && strcmp(allowed, ".")) {
1249
0
        warning(_("safe.directory '%s' not absolute"),
1250
0
          allowed);
1251
0
        goto next;
1252
0
      }
1253
1254
      /*
1255
       * A .gitconfig in $HOME may be shared across
1256
       * different machines and safe.directory entries
1257
       * may or may not exist as paths on all of these
1258
       * machines.  In other words, it is not a warning
1259
       * worthy event when there is no such path on this
1260
       * machine---the entry may be useful elsewhere.
1261
       */
1262
0
      normalized = real_pathdup(allowed, 0);
1263
0
      if (!normalized)
1264
0
        goto next;
1265
1266
0
      if (ends_with(normalized, "/*")) {
1267
0
        size_t len = strlen(normalized);
1268
0
        if (!fspathncmp(normalized, data->path, len - 1))
1269
0
          data->is_safe = 1;
1270
0
      } else if (!fspathcmp(data->path, normalized)) {
1271
0
        data->is_safe = 1;
1272
0
      }
1273
0
    next:
1274
0
      free(normalized);
1275
0
      free(allowed);
1276
0
    }
1277
0
  }
1278
1279
0
  return 0;
1280
0
}
1281
1282
/*
1283
 * Check if a repository is safe, by verifying the ownership of the
1284
 * worktree (if any), the git directory, and the gitfile (if any).
1285
 *
1286
 * Exemptions for known-safe repositories can be added via `safe.directory`
1287
 * config settings; for non-bare repositories, their worktree needs to be
1288
 * added, for bare ones their git directory.
1289
 */
1290
static int ensure_valid_ownership(const char *gitfile,
1291
          const char *worktree, const char *gitdir,
1292
          struct strbuf *report)
1293
0
{
1294
0
  struct safe_directory_data data = { 0 };
1295
1296
0
  if (!git_env_bool("GIT_TEST_ASSUME_DIFFERENT_OWNER", 0) &&
1297
0
      (!gitfile || is_path_owned_by_current_user(gitfile, report)) &&
1298
0
      (!worktree || is_path_owned_by_current_user(worktree, report)) &&
1299
0
      (!gitdir || is_path_owned_by_current_user(gitdir, report)))
1300
0
    return 1;
1301
1302
  /*
1303
   * normalize the data.path for comparison with normalized paths
1304
   * that come from the configuration file.  The path is unsafe
1305
   * if it cannot be normalized.
1306
   */
1307
0
  data.path = real_pathdup(worktree ? worktree : gitdir, 0);
1308
0
  if (!data.path)
1309
0
    return 0;
1310
1311
  /*
1312
   * data.path is the "path" that identifies the repository and it is
1313
   * constant regardless of what failed above. data.is_safe should be
1314
   * initialized to false, and might be changed by the callback.
1315
   */
1316
0
  git_protected_config(safe_directory_cb, &data);
1317
1318
0
  free(data.path);
1319
0
  return data.is_safe;
1320
0
}
1321
1322
void die_upon_dubious_ownership(const char *gitfile, const char *worktree,
1323
        const char *gitdir)
1324
0
{
1325
0
  struct strbuf report = STRBUF_INIT, quoted = STRBUF_INIT;
1326
0
  const char *path;
1327
1328
0
  if (ensure_valid_ownership(gitfile, worktree, gitdir, &report))
1329
0
    return;
1330
1331
0
  strbuf_complete(&report, '\n');
1332
0
  path = gitfile ? gitfile : gitdir;
1333
0
  sq_quote_buf_pretty(&quoted, path);
1334
1335
0
  die(_("detected dubious ownership in repository at '%s'\n"
1336
0
        "%s"
1337
0
        "To add an exception for this directory, call:\n"
1338
0
        "\n"
1339
0
        "\tgit config --global --add safe.directory %s"),
1340
0
      path, report.buf, quoted.buf);
1341
0
}
1342
1343
static int allowed_bare_repo_cb(const char *key, const char *value,
1344
        const struct config_context *ctx UNUSED,
1345
        void *d)
1346
0
{
1347
0
  enum allowed_bare_repo *allowed_bare_repo = d;
1348
1349
0
  if (strcasecmp(key, "safe.bareRepository"))
1350
0
    return 0;
1351
1352
0
  if (!strcmp(value, "explicit")) {
1353
0
    *allowed_bare_repo = ALLOWED_BARE_REPO_EXPLICIT;
1354
0
    return 0;
1355
0
  }
1356
0
  if (!strcmp(value, "all")) {
1357
0
    *allowed_bare_repo = ALLOWED_BARE_REPO_ALL;
1358
0
    return 0;
1359
0
  }
1360
0
  return -1;
1361
0
}
1362
1363
static enum allowed_bare_repo get_allowed_bare_repo(void)
1364
0
{
1365
0
  enum allowed_bare_repo result = ALLOWED_BARE_REPO_ALL;
1366
0
  git_protected_config(allowed_bare_repo_cb, &result);
1367
0
  return result;
1368
0
}
1369
1370
static const char *allowed_bare_repo_to_string(
1371
  enum allowed_bare_repo allowed_bare_repo)
1372
0
{
1373
0
  switch (allowed_bare_repo) {
1374
0
  case ALLOWED_BARE_REPO_EXPLICIT:
1375
0
    return "explicit";
1376
0
  case ALLOWED_BARE_REPO_ALL:
1377
0
    return "all";
1378
0
  default:
1379
0
    BUG("invalid allowed_bare_repo %d",
1380
0
        allowed_bare_repo);
1381
0
  }
1382
0
  return NULL;
1383
0
}
1384
1385
static int is_implicit_bare_repo(const char *path)
1386
0
{
1387
  /*
1388
   * what we found is a ".git" directory at the root of
1389
   * the working tree.
1390
   */
1391
0
  if (ends_with_path_components(path, ".git"))
1392
0
    return 1;
1393
1394
  /*
1395
   * we are inside $GIT_DIR of a secondary worktree of a
1396
   * non-bare repository.
1397
   */
1398
0
  if (strstr(path, "/.git/worktrees/"))
1399
0
    return 1;
1400
1401
  /*
1402
   * we are inside $GIT_DIR of a worktree of a non-embedded
1403
   * submodule, whose superproject is not a bare repository.
1404
   */
1405
0
  if (strstr(path, "/.git/modules/"))
1406
0
    return 1;
1407
1408
0
  return 0;
1409
0
}
1410
1411
/*
1412
 * We cannot decide in this function whether we are in the work tree or
1413
 * not, since the config can only be read _after_ this function was called.
1414
 *
1415
 * Also, we avoid changing any global state (such as the current working
1416
 * directory) to allow early callers.
1417
 *
1418
 * The directory where the search should start needs to be passed in via the
1419
 * `dir` parameter; upon return, the `dir` buffer will contain the path of
1420
 * the directory where the search ended, and `gitdir` will contain the path of
1421
 * the discovered .git/ directory, if any. If `gitdir` is not absolute, it
1422
 * is relative to `dir` (i.e. *not* necessarily the cwd).
1423
 */
1424
static enum discovery_result setup_git_directory_gently_1(struct strbuf *dir,
1425
                struct strbuf *gitdir,
1426
                struct strbuf *report,
1427
                int die_on_error)
1428
0
{
1429
0
  const char *env_ceiling_dirs = getenv(CEILING_DIRECTORIES_ENVIRONMENT);
1430
0
  struct string_list ceiling_dirs = STRING_LIST_INIT_DUP;
1431
0
  const char *gitdirenv;
1432
0
  int ceil_offset = -1, min_offset = offset_1st_component(dir->buf);
1433
0
  dev_t current_device = 0;
1434
0
  int one_filesystem = 1;
1435
1436
  /*
1437
   * If GIT_DIR is set explicitly, we're not going
1438
   * to do any discovery, but we still do repository
1439
   * validation.
1440
   */
1441
0
  gitdirenv = getenv(GIT_DIR_ENVIRONMENT);
1442
0
  if (gitdirenv) {
1443
0
    strbuf_addstr(gitdir, gitdirenv);
1444
0
    return GIT_DIR_EXPLICIT;
1445
0
  }
1446
1447
0
  if (env_ceiling_dirs) {
1448
0
    int empty_entry_found = 0;
1449
1450
0
    string_list_split(&ceiling_dirs, env_ceiling_dirs, PATH_SEP, -1);
1451
0
    filter_string_list(&ceiling_dirs, 0,
1452
0
           canonicalize_ceiling_entry, &empty_entry_found);
1453
0
    ceil_offset = longest_ancestor_length(dir->buf, &ceiling_dirs);
1454
0
    string_list_clear(&ceiling_dirs, 0);
1455
0
  }
1456
1457
0
  if (ceil_offset < 0)
1458
0
    ceil_offset = min_offset - 2;
1459
1460
0
  if (min_offset && min_offset == dir->len &&
1461
0
      !is_dir_sep(dir->buf[min_offset - 1])) {
1462
0
    strbuf_addch(dir, '/');
1463
0
    min_offset++;
1464
0
  }
1465
1466
  /*
1467
   * Test in the following order (relative to the dir):
1468
   * - .git (file containing "gitdir: <path>")
1469
   * - .git/
1470
   * - ./ (bare)
1471
   * - ../.git
1472
   * - ../.git/
1473
   * - ../ (bare)
1474
   * - ../../.git
1475
   *   etc.
1476
   */
1477
0
  one_filesystem = !git_env_bool("GIT_DISCOVERY_ACROSS_FILESYSTEM", 0);
1478
0
  if (one_filesystem)
1479
0
    current_device = get_device_or_die(dir->buf, NULL, 0);
1480
0
  for (;;) {
1481
0
    int offset = dir->len, error_code = 0;
1482
0
    char *gitdir_path = NULL;
1483
0
    char *gitfile = NULL;
1484
1485
0
    if (offset > min_offset)
1486
0
      strbuf_addch(dir, '/');
1487
0
    strbuf_addstr(dir, DEFAULT_GIT_DIR_ENVIRONMENT);
1488
0
    gitdirenv = read_gitfile_gently(dir->buf, die_on_error ?
1489
0
            NULL : &error_code);
1490
0
    if (!gitdirenv) {
1491
0
      if (die_on_error ||
1492
0
          error_code == READ_GITFILE_ERR_NOT_A_FILE) {
1493
        /* NEEDSWORK: fail if .git is not file nor dir */
1494
0
        if (is_git_directory(dir->buf)) {
1495
0
          gitdirenv = DEFAULT_GIT_DIR_ENVIRONMENT;
1496
0
          gitdir_path = xstrdup(dir->buf);
1497
0
        }
1498
0
      } else if (error_code != READ_GITFILE_ERR_STAT_FAILED)
1499
0
        return GIT_DIR_INVALID_GITFILE;
1500
0
    } else
1501
0
      gitfile = xstrdup(dir->buf);
1502
    /*
1503
     * Earlier, we tentatively added DEFAULT_GIT_DIR_ENVIRONMENT
1504
     * to check that directory for a repository.
1505
     * Now trim that tentative addition away, because we want to
1506
     * focus on the real directory we are in.
1507
     */
1508
0
    strbuf_setlen(dir, offset);
1509
0
    if (gitdirenv) {
1510
0
      enum discovery_result ret;
1511
0
      const char *gitdir_candidate =
1512
0
        gitdir_path ? gitdir_path : gitdirenv;
1513
1514
0
      if (ensure_valid_ownership(gitfile, dir->buf,
1515
0
               gitdir_candidate, report)) {
1516
0
        strbuf_addstr(gitdir, gitdirenv);
1517
0
        ret = GIT_DIR_DISCOVERED;
1518
0
      } else
1519
0
        ret = GIT_DIR_INVALID_OWNERSHIP;
1520
1521
      /*
1522
       * Earlier, during discovery, we might have allocated
1523
       * string copies for gitdir_path or gitfile so make
1524
       * sure we don't leak by freeing them now, before
1525
       * leaving the loop and function.
1526
       *
1527
       * Note: gitdirenv will be non-NULL whenever these are
1528
       * allocated, therefore we need not take care of releasing
1529
       * them outside of this conditional block.
1530
       */
1531
0
      free(gitdir_path);
1532
0
      free(gitfile);
1533
1534
0
      return ret;
1535
0
    }
1536
1537
0
    if (is_git_directory(dir->buf)) {
1538
0
      trace2_data_string("setup", NULL, "implicit-bare-repository", dir->buf);
1539
0
      if (get_allowed_bare_repo() == ALLOWED_BARE_REPO_EXPLICIT &&
1540
0
          !is_implicit_bare_repo(dir->buf))
1541
0
        return GIT_DIR_DISALLOWED_BARE;
1542
0
      if (!ensure_valid_ownership(NULL, NULL, dir->buf, report))
1543
0
        return GIT_DIR_INVALID_OWNERSHIP;
1544
0
      strbuf_addstr(gitdir, ".");
1545
0
      return GIT_DIR_BARE;
1546
0
    }
1547
1548
0
    if (offset <= min_offset)
1549
0
      return GIT_DIR_HIT_CEILING;
1550
1551
0
    while (--offset > ceil_offset && !is_dir_sep(dir->buf[offset]))
1552
0
      ; /* continue */
1553
0
    if (offset <= ceil_offset)
1554
0
      return GIT_DIR_HIT_CEILING;
1555
1556
0
    strbuf_setlen(dir, offset > min_offset ?  offset : min_offset);
1557
0
    if (one_filesystem &&
1558
0
        current_device != get_device_or_die(dir->buf, NULL, offset))
1559
0
      return GIT_DIR_HIT_MOUNT_POINT;
1560
0
  }
1561
0
}
1562
1563
enum discovery_result discover_git_directory_reason(struct strbuf *commondir,
1564
                struct strbuf *gitdir)
1565
0
{
1566
0
  struct strbuf dir = STRBUF_INIT, err = STRBUF_INIT;
1567
0
  size_t gitdir_offset = gitdir->len, cwd_len;
1568
0
  size_t commondir_offset = commondir->len;
1569
0
  struct repository_format candidate = REPOSITORY_FORMAT_INIT;
1570
0
  enum discovery_result result;
1571
1572
0
  if (strbuf_getcwd(&dir))
1573
0
    return GIT_DIR_CWD_FAILURE;
1574
1575
0
  cwd_len = dir.len;
1576
0
  result = setup_git_directory_gently_1(&dir, gitdir, NULL, 0);
1577
0
  if (result <= 0) {
1578
0
    strbuf_release(&dir);
1579
0
    return result;
1580
0
  }
1581
1582
  /*
1583
   * The returned gitdir is relative to dir, and if dir does not reflect
1584
   * the current working directory, we simply make the gitdir absolute.
1585
   */
1586
0
  if (dir.len < cwd_len && !is_absolute_path(gitdir->buf + gitdir_offset)) {
1587
    /* Avoid a trailing "/." */
1588
0
    if (!strcmp(".", gitdir->buf + gitdir_offset))
1589
0
      strbuf_setlen(gitdir, gitdir_offset);
1590
0
    else
1591
0
      strbuf_addch(&dir, '/');
1592
0
    strbuf_insert(gitdir, gitdir_offset, dir.buf, dir.len);
1593
0
  }
1594
1595
0
  get_common_dir(commondir, gitdir->buf + gitdir_offset);
1596
1597
0
  strbuf_reset(&dir);
1598
0
  strbuf_addf(&dir, "%s/config", commondir->buf + commondir_offset);
1599
0
  read_repository_format(&candidate, dir.buf);
1600
0
  strbuf_release(&dir);
1601
1602
0
  if (verify_repository_format(&candidate, &err) < 0) {
1603
0
    warning("ignoring git dir '%s': %s",
1604
0
      gitdir->buf + gitdir_offset, err.buf);
1605
0
    strbuf_release(&err);
1606
0
    strbuf_setlen(commondir, commondir_offset);
1607
0
    strbuf_setlen(gitdir, gitdir_offset);
1608
0
    clear_repository_format(&candidate);
1609
0
    return GIT_DIR_INVALID_FORMAT;
1610
0
  }
1611
1612
0
  clear_repository_format(&candidate);
1613
0
  return result;
1614
0
}
1615
1616
const char *setup_git_directory_gently(int *nongit_ok)
1617
0
{
1618
0
  static struct strbuf cwd = STRBUF_INIT;
1619
0
  struct strbuf dir = STRBUF_INIT, gitdir = STRBUF_INIT, report = STRBUF_INIT;
1620
0
  const char *prefix = NULL;
1621
0
  struct repository_format repo_fmt = REPOSITORY_FORMAT_INIT;
1622
1623
  /*
1624
   * We may have read an incomplete configuration before
1625
   * setting-up the git directory. If so, clear the cache so
1626
   * that the next queries to the configuration reload complete
1627
   * configuration (including the per-repo config file that we
1628
   * ignored previously).
1629
   */
1630
0
  git_config_clear();
1631
1632
  /*
1633
   * Let's assume that we are in a git repository.
1634
   * If it turns out later that we are somewhere else, the value will be
1635
   * updated accordingly.
1636
   */
1637
0
  if (nongit_ok)
1638
0
    *nongit_ok = 0;
1639
1640
0
  if (strbuf_getcwd(&cwd))
1641
0
    die_errno(_("Unable to read current working directory"));
1642
0
  strbuf_addbuf(&dir, &cwd);
1643
1644
0
  switch (setup_git_directory_gently_1(&dir, &gitdir, &report, 1)) {
1645
0
  case GIT_DIR_EXPLICIT:
1646
0
    prefix = setup_explicit_git_dir(gitdir.buf, &cwd, &repo_fmt, nongit_ok);
1647
0
    break;
1648
0
  case GIT_DIR_DISCOVERED:
1649
0
    if (dir.len < cwd.len && chdir(dir.buf))
1650
0
      die(_("cannot change to '%s'"), dir.buf);
1651
0
    prefix = setup_discovered_git_dir(gitdir.buf, &cwd, dir.len,
1652
0
              &repo_fmt, nongit_ok);
1653
0
    break;
1654
0
  case GIT_DIR_BARE:
1655
0
    if (dir.len < cwd.len && chdir(dir.buf))
1656
0
      die(_("cannot change to '%s'"), dir.buf);
1657
0
    prefix = setup_bare_git_dir(&cwd, dir.len, &repo_fmt, nongit_ok);
1658
0
    break;
1659
0
  case GIT_DIR_HIT_CEILING:
1660
0
    if (!nongit_ok)
1661
0
      die(_("not a git repository (or any of the parent directories): %s"),
1662
0
          DEFAULT_GIT_DIR_ENVIRONMENT);
1663
0
    *nongit_ok = 1;
1664
0
    break;
1665
0
  case GIT_DIR_HIT_MOUNT_POINT:
1666
0
    if (!nongit_ok)
1667
0
      die(_("not a git repository (or any parent up to mount point %s)\n"
1668
0
            "Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set)."),
1669
0
          dir.buf);
1670
0
    *nongit_ok = 1;
1671
0
    break;
1672
0
  case GIT_DIR_INVALID_OWNERSHIP:
1673
0
    if (!nongit_ok) {
1674
0
      struct strbuf quoted = STRBUF_INIT;
1675
1676
0
      strbuf_complete(&report, '\n');
1677
0
      sq_quote_buf_pretty(&quoted, dir.buf);
1678
0
      die(_("detected dubious ownership in repository at '%s'\n"
1679
0
            "%s"
1680
0
            "To add an exception for this directory, call:\n"
1681
0
            "\n"
1682
0
            "\tgit config --global --add safe.directory %s"),
1683
0
          dir.buf, report.buf, quoted.buf);
1684
0
    }
1685
0
    *nongit_ok = 1;
1686
0
    break;
1687
0
  case GIT_DIR_DISALLOWED_BARE:
1688
0
    if (!nongit_ok) {
1689
0
      die(_("cannot use bare repository '%s' (safe.bareRepository is '%s')"),
1690
0
          dir.buf,
1691
0
          allowed_bare_repo_to_string(get_allowed_bare_repo()));
1692
0
    }
1693
0
    *nongit_ok = 1;
1694
0
    break;
1695
0
  case GIT_DIR_CWD_FAILURE:
1696
0
  case GIT_DIR_INVALID_FORMAT:
1697
    /*
1698
     * As a safeguard against setup_git_directory_gently_1 returning
1699
     * these values, fallthrough to BUG. Otherwise it is possible to
1700
     * set startup_info->have_repository to 1 when we did nothing to
1701
     * find a repository.
1702
     */
1703
0
  default:
1704
0
    BUG("unhandled setup_git_directory_gently_1() result");
1705
0
  }
1706
1707
  /*
1708
   * At this point, nongit_ok is stable. If it is non-NULL and points
1709
   * to a non-zero value, then this means that we haven't found a
1710
   * repository and that the caller expects startup_info to reflect
1711
   * this.
1712
   *
1713
   * Regardless of the state of nongit_ok, startup_info->prefix and
1714
   * the GIT_PREFIX environment variable must always match. For details
1715
   * see Documentation/config/alias.txt.
1716
   */
1717
0
  if (nongit_ok && *nongit_ok)
1718
0
    startup_info->have_repository = 0;
1719
0
  else
1720
0
    startup_info->have_repository = 1;
1721
1722
  /*
1723
   * Not all paths through the setup code will call 'set_git_dir()' (which
1724
   * directly sets up the environment) so in order to guarantee that the
1725
   * environment is in a consistent state after setup, explicitly setup
1726
   * the environment if we have a repository.
1727
   *
1728
   * NEEDSWORK: currently we allow bogus GIT_DIR values to be set in some
1729
   * code paths so we also need to explicitly setup the environment if
1730
   * the user has set GIT_DIR.  It may be beneficial to disallow bogus
1731
   * GIT_DIR values at some point in the future.
1732
   */
1733
0
  if (/* GIT_DIR_EXPLICIT, GIT_DIR_DISCOVERED, GIT_DIR_BARE */
1734
0
      startup_info->have_repository ||
1735
      /* GIT_DIR_EXPLICIT */
1736
0
      getenv(GIT_DIR_ENVIRONMENT)) {
1737
0
    if (!the_repository->gitdir) {
1738
0
      const char *gitdir = getenv(GIT_DIR_ENVIRONMENT);
1739
0
      if (!gitdir)
1740
0
        gitdir = DEFAULT_GIT_DIR_ENVIRONMENT;
1741
0
      setup_git_env(gitdir);
1742
0
    }
1743
0
    if (startup_info->have_repository) {
1744
0
      repo_set_hash_algo(the_repository, repo_fmt.hash_algo);
1745
0
      repo_set_compat_hash_algo(the_repository,
1746
0
              repo_fmt.compat_hash_algo);
1747
0
      repo_set_ref_storage_format(the_repository,
1748
0
                repo_fmt.ref_storage_format);
1749
0
      the_repository->repository_format_worktree_config =
1750
0
        repo_fmt.worktree_config;
1751
      /* take ownership of repo_fmt.partial_clone */
1752
0
      the_repository->repository_format_partial_clone =
1753
0
        repo_fmt.partial_clone;
1754
0
      repo_fmt.partial_clone = NULL;
1755
0
    }
1756
0
  }
1757
  /*
1758
   * Since precompose_string_if_needed() needs to look at
1759
   * the core.precomposeunicode configuration, this
1760
   * has to happen after the above block that finds
1761
   * out where the repository is, i.e. a preparation
1762
   * for calling git_config_get_bool().
1763
   */
1764
0
  if (prefix) {
1765
0
    prefix = precompose_string_if_needed(prefix);
1766
0
    startup_info->prefix = prefix;
1767
0
    setenv(GIT_PREFIX_ENVIRONMENT, prefix, 1);
1768
0
  } else {
1769
0
    startup_info->prefix = NULL;
1770
0
    setenv(GIT_PREFIX_ENVIRONMENT, "", 1);
1771
0
  }
1772
1773
0
  setup_original_cwd();
1774
1775
0
  strbuf_release(&dir);
1776
0
  strbuf_release(&gitdir);
1777
0
  strbuf_release(&report);
1778
0
  clear_repository_format(&repo_fmt);
1779
1780
0
  return prefix;
1781
0
}
1782
1783
int git_config_perm(const char *var, const char *value)
1784
0
{
1785
0
  int i;
1786
0
  char *endptr;
1787
1788
0
  if (!value)
1789
0
    return PERM_GROUP;
1790
1791
0
  if (!strcmp(value, "umask"))
1792
0
    return PERM_UMASK;
1793
0
  if (!strcmp(value, "group"))
1794
0
    return PERM_GROUP;
1795
0
  if (!strcmp(value, "all") ||
1796
0
      !strcmp(value, "world") ||
1797
0
      !strcmp(value, "everybody"))
1798
0
    return PERM_EVERYBODY;
1799
1800
  /* Parse octal numbers */
1801
0
  i = strtol(value, &endptr, 8);
1802
1803
  /* If not an octal number, maybe true/false? */
1804
0
  if (*endptr != 0)
1805
0
    return git_config_bool(var, value) ? PERM_GROUP : PERM_UMASK;
1806
1807
  /*
1808
   * Treat values 0, 1 and 2 as compatibility cases, otherwise it is
1809
   * a chmod value to restrict to.
1810
   */
1811
0
  switch (i) {
1812
0
  case PERM_UMASK:               /* 0 */
1813
0
    return PERM_UMASK;
1814
0
  case OLD_PERM_GROUP:           /* 1 */
1815
0
    return PERM_GROUP;
1816
0
  case OLD_PERM_EVERYBODY:       /* 2 */
1817
0
    return PERM_EVERYBODY;
1818
0
  }
1819
1820
  /* A filemode value was given: 0xxx */
1821
1822
0
  if ((i & 0600) != 0600)
1823
0
    die(_("problem with core.sharedRepository filemode value "
1824
0
        "(0%.3o).\nThe owner of files must always have "
1825
0
        "read and write permissions."), i);
1826
1827
  /*
1828
   * Mask filemode value. Others can not get write permission.
1829
   * x flags for directories are handled separately.
1830
   */
1831
0
  return -(i & 0666);
1832
0
}
1833
1834
void check_repository_format(struct repository_format *fmt)
1835
0
{
1836
0
  struct repository_format repo_fmt = REPOSITORY_FORMAT_INIT;
1837
0
  if (!fmt)
1838
0
    fmt = &repo_fmt;
1839
0
  check_repository_format_gently(get_git_dir(), fmt, NULL);
1840
0
  startup_info->have_repository = 1;
1841
0
  repo_set_hash_algo(the_repository, fmt->hash_algo);
1842
0
  repo_set_compat_hash_algo(the_repository, fmt->compat_hash_algo);
1843
0
  repo_set_ref_storage_format(the_repository,
1844
0
            fmt->ref_storage_format);
1845
0
  the_repository->repository_format_worktree_config =
1846
0
    fmt->worktree_config;
1847
0
  the_repository->repository_format_partial_clone =
1848
0
    xstrdup_or_null(fmt->partial_clone);
1849
0
  clear_repository_format(&repo_fmt);
1850
0
}
1851
1852
/*
1853
 * Returns the "prefix", a path to the current working directory
1854
 * relative to the work tree root, or NULL, if the current working
1855
 * directory is not a strict subdirectory of the work tree root. The
1856
 * prefix always ends with a '/' character.
1857
 */
1858
const char *setup_git_directory(void)
1859
0
{
1860
0
  return setup_git_directory_gently(NULL);
1861
0
}
1862
1863
const char *resolve_gitdir_gently(const char *suspect, int *return_error_code)
1864
0
{
1865
0
  if (is_git_directory(suspect))
1866
0
    return suspect;
1867
0
  return read_gitfile_gently(suspect, return_error_code);
1868
0
}
1869
1870
/* if any standard file descriptor is missing open it to /dev/null */
1871
void sanitize_stdfds(void)
1872
0
{
1873
0
  int fd = xopen("/dev/null", O_RDWR);
1874
0
  while (fd < 2)
1875
0
    fd = xdup(fd);
1876
0
  if (fd > 2)
1877
0
    close(fd);
1878
0
}
1879
1880
int daemonize(void)
1881
0
{
1882
#ifdef NO_POSIX_GOODIES
1883
  errno = ENOSYS;
1884
  return -1;
1885
#else
1886
0
  switch (fork()) {
1887
0
    case 0:
1888
0
      break;
1889
0
    case -1:
1890
0
      die_errno(_("fork failed"));
1891
0
    default:
1892
0
      exit(0);
1893
0
  }
1894
0
  if (setsid() == -1)
1895
0
    die_errno(_("setsid failed"));
1896
0
  close(0);
1897
0
  close(1);
1898
0
  close(2);
1899
0
  sanitize_stdfds();
1900
0
  return 0;
1901
0
#endif
1902
0
}
1903
1904
struct template_dir_cb_data {
1905
  char *path;
1906
  int initialized;
1907
};
1908
1909
static int template_dir_cb(const char *key, const char *value,
1910
         const struct config_context *ctx UNUSED, void *d)
1911
0
{
1912
0
  struct template_dir_cb_data *data = d;
1913
1914
0
  if (strcmp(key, "init.templatedir"))
1915
0
    return 0;
1916
1917
0
  if (!value) {
1918
0
    data->path = NULL;
1919
0
  } else {
1920
0
    char *path = NULL;
1921
1922
0
    FREE_AND_NULL(data->path);
1923
0
    if (!git_config_pathname(&path, key, value))
1924
0
      data->path = path ? path : xstrdup(value);
1925
0
  }
1926
1927
0
  return 0;
1928
0
}
1929
1930
const char *get_template_dir(const char *option_template)
1931
0
{
1932
0
  const char *template_dir = option_template;
1933
1934
0
  if (!template_dir)
1935
0
    template_dir = getenv(TEMPLATE_DIR_ENVIRONMENT);
1936
0
  if (!template_dir) {
1937
0
    static struct template_dir_cb_data data;
1938
1939
0
    if (!data.initialized) {
1940
0
      git_protected_config(template_dir_cb, &data);
1941
0
      data.initialized = 1;
1942
0
    }
1943
0
    template_dir = data.path;
1944
0
  }
1945
0
  if (!template_dir) {
1946
0
    static char *dir;
1947
1948
0
    if (!dir)
1949
0
      dir = system_path(DEFAULT_GIT_TEMPLATE_DIR);
1950
0
    template_dir = dir;
1951
0
  }
1952
0
  return template_dir;
1953
0
}
1954
1955
#ifdef NO_TRUSTABLE_FILEMODE
1956
#define TEST_FILEMODE 0
1957
#else
1958
0
#define TEST_FILEMODE 1
1959
#endif
1960
1961
0
#define GIT_DEFAULT_HASH_ENVIRONMENT "GIT_DEFAULT_HASH"
1962
1963
static void copy_templates_1(struct strbuf *path, struct strbuf *template_path,
1964
           DIR *dir)
1965
0
{
1966
0
  size_t path_baselen = path->len;
1967
0
  size_t template_baselen = template_path->len;
1968
0
  struct dirent *de;
1969
1970
  /* Note: if ".git/hooks" file exists in the repository being
1971
   * re-initialized, /etc/core-git/templates/hooks/update would
1972
   * cause "git init" to fail here.  I think this is sane but
1973
   * it means that the set of templates we ship by default, along
1974
   * with the way the namespace under .git/ is organized, should
1975
   * be really carefully chosen.
1976
   */
1977
0
  safe_create_dir(path->buf, 1);
1978
0
  while ((de = readdir(dir)) != NULL) {
1979
0
    struct stat st_git, st_template;
1980
0
    int exists = 0;
1981
1982
0
    strbuf_setlen(path, path_baselen);
1983
0
    strbuf_setlen(template_path, template_baselen);
1984
1985
0
    if (de->d_name[0] == '.')
1986
0
      continue;
1987
0
    strbuf_addstr(path, de->d_name);
1988
0
    strbuf_addstr(template_path, de->d_name);
1989
0
    if (lstat(path->buf, &st_git)) {
1990
0
      if (errno != ENOENT)
1991
0
        die_errno(_("cannot stat '%s'"), path->buf);
1992
0
    }
1993
0
    else
1994
0
      exists = 1;
1995
1996
0
    if (lstat(template_path->buf, &st_template))
1997
0
      die_errno(_("cannot stat template '%s'"), template_path->buf);
1998
1999
0
    if (S_ISDIR(st_template.st_mode)) {
2000
0
      DIR *subdir = opendir(template_path->buf);
2001
0
      if (!subdir)
2002
0
        die_errno(_("cannot opendir '%s'"), template_path->buf);
2003
0
      strbuf_addch(path, '/');
2004
0
      strbuf_addch(template_path, '/');
2005
0
      copy_templates_1(path, template_path, subdir);
2006
0
      closedir(subdir);
2007
0
    }
2008
0
    else if (exists)
2009
0
      continue;
2010
0
    else if (S_ISLNK(st_template.st_mode)) {
2011
0
      struct strbuf lnk = STRBUF_INIT;
2012
0
      if (strbuf_readlink(&lnk, template_path->buf,
2013
0
              st_template.st_size) < 0)
2014
0
        die_errno(_("cannot readlink '%s'"), template_path->buf);
2015
0
      if (symlink(lnk.buf, path->buf))
2016
0
        die_errno(_("cannot symlink '%s' '%s'"),
2017
0
            lnk.buf, path->buf);
2018
0
      strbuf_release(&lnk);
2019
0
    }
2020
0
    else if (S_ISREG(st_template.st_mode)) {
2021
0
      if (copy_file(path->buf, template_path->buf, st_template.st_mode))
2022
0
        die_errno(_("cannot copy '%s' to '%s'"),
2023
0
            template_path->buf, path->buf);
2024
0
    }
2025
0
    else
2026
0
      error(_("ignoring template %s"), template_path->buf);
2027
0
  }
2028
0
}
2029
2030
static void copy_templates(const char *option_template)
2031
0
{
2032
0
  const char *template_dir = get_template_dir(option_template);
2033
0
  struct strbuf path = STRBUF_INIT;
2034
0
  struct strbuf template_path = STRBUF_INIT;
2035
0
  size_t template_len;
2036
0
  struct repository_format template_format = REPOSITORY_FORMAT_INIT;
2037
0
  struct strbuf err = STRBUF_INIT;
2038
0
  DIR *dir;
2039
0
  char *to_free = NULL;
2040
2041
0
  if (!template_dir || !*template_dir)
2042
0
    return;
2043
2044
0
  strbuf_addstr(&template_path, template_dir);
2045
0
  strbuf_complete(&template_path, '/');
2046
0
  template_len = template_path.len;
2047
2048
0
  dir = opendir(template_path.buf);
2049
0
  if (!dir) {
2050
0
    warning(_("templates not found in %s"), template_dir);
2051
0
    goto free_return;
2052
0
  }
2053
2054
  /* Make sure that template is from the correct vintage */
2055
0
  strbuf_addstr(&template_path, "config");
2056
0
  read_repository_format(&template_format, template_path.buf);
2057
0
  strbuf_setlen(&template_path, template_len);
2058
2059
  /*
2060
   * No mention of version at all is OK, but anything else should be
2061
   * verified.
2062
   */
2063
0
  if (template_format.version >= 0 &&
2064
0
      verify_repository_format(&template_format, &err) < 0) {
2065
0
    warning(_("not copying templates from '%s': %s"),
2066
0
        template_dir, err.buf);
2067
0
    strbuf_release(&err);
2068
0
    goto close_free_return;
2069
0
  }
2070
2071
0
  strbuf_addstr(&path, get_git_common_dir());
2072
0
  strbuf_complete(&path, '/');
2073
0
  copy_templates_1(&path, &template_path, dir);
2074
0
close_free_return:
2075
0
  closedir(dir);
2076
0
free_return:
2077
0
  free(to_free);
2078
0
  strbuf_release(&path);
2079
0
  strbuf_release(&template_path);
2080
0
  clear_repository_format(&template_format);
2081
0
}
2082
2083
/*
2084
 * If the git_dir is not directly inside the working tree, then git will not
2085
 * find it by default, and we need to set the worktree explicitly.
2086
 */
2087
static int needs_work_tree_config(const char *git_dir, const char *work_tree)
2088
0
{
2089
0
  if (!strcmp(work_tree, "/") && !strcmp(git_dir, "/.git"))
2090
0
    return 0;
2091
0
  if (skip_prefix(git_dir, work_tree, &git_dir) &&
2092
0
      !strcmp(git_dir, "/.git"))
2093
0
    return 0;
2094
0
  return 1;
2095
0
}
2096
2097
void initialize_repository_version(int hash_algo,
2098
           enum ref_storage_format ref_storage_format,
2099
           int reinit)
2100
0
{
2101
0
  char repo_version_string[10];
2102
0
  int repo_version = GIT_REPO_VERSION;
2103
2104
  /*
2105
   * Note that we initialize the repository version to 1 when the ref
2106
   * storage format is unknown. This is on purpose so that we can add the
2107
   * correct object format to the config during git-clone(1). The format
2108
   * version will get adjusted by git-clone(1) once it has learned about
2109
   * the remote repository's format.
2110
   */
2111
0
  if (hash_algo != GIT_HASH_SHA1 ||
2112
0
      ref_storage_format != REF_STORAGE_FORMAT_FILES)
2113
0
    repo_version = GIT_REPO_VERSION_READ;
2114
2115
  /* This forces creation of new config file */
2116
0
  xsnprintf(repo_version_string, sizeof(repo_version_string),
2117
0
      "%d", repo_version);
2118
0
  git_config_set("core.repositoryformatversion", repo_version_string);
2119
2120
0
  if (hash_algo != GIT_HASH_SHA1 && hash_algo != GIT_HASH_UNKNOWN)
2121
0
    git_config_set("extensions.objectformat",
2122
0
             hash_algos[hash_algo].name);
2123
0
  else if (reinit)
2124
0
    git_config_set_gently("extensions.objectformat", NULL);
2125
2126
0
  if (ref_storage_format != REF_STORAGE_FORMAT_FILES)
2127
0
    git_config_set("extensions.refstorage",
2128
0
             ref_storage_format_to_name(ref_storage_format));
2129
0
  else if (reinit)
2130
0
    git_config_set_gently("extensions.refstorage", NULL);
2131
0
}
2132
2133
static int is_reinit(void)
2134
0
{
2135
0
  struct strbuf buf = STRBUF_INIT;
2136
0
  char junk[2];
2137
0
  int ret;
2138
2139
0
  git_path_buf(&buf, "HEAD");
2140
0
  ret = !access(buf.buf, R_OK) || readlink(buf.buf, junk, sizeof(junk) - 1) != -1;
2141
0
  strbuf_release(&buf);
2142
0
  return ret;
2143
0
}
2144
2145
void create_reference_database(enum ref_storage_format ref_storage_format,
2146
             const char *initial_branch, int quiet)
2147
0
{
2148
0
  struct strbuf err = STRBUF_INIT;
2149
0
  char *to_free = NULL;
2150
0
  int reinit = is_reinit();
2151
2152
0
  repo_set_ref_storage_format(the_repository, ref_storage_format);
2153
0
  if (ref_store_create_on_disk(get_main_ref_store(the_repository), 0, &err))
2154
0
    die("failed to set up refs db: %s", err.buf);
2155
2156
  /*
2157
   * Point the HEAD symref to the initial branch with if HEAD does
2158
   * not yet exist.
2159
   */
2160
0
  if (!reinit) {
2161
0
    char *ref;
2162
2163
0
    if (!initial_branch)
2164
0
      initial_branch = to_free =
2165
0
        repo_default_branch_name(the_repository, quiet);
2166
2167
0
    ref = xstrfmt("refs/heads/%s", initial_branch);
2168
0
    if (check_refname_format(ref, 0) < 0)
2169
0
      die(_("invalid initial branch name: '%s'"),
2170
0
          initial_branch);
2171
2172
0
    if (refs_update_symref(get_main_ref_store(the_repository), "HEAD", ref, NULL) < 0)
2173
0
      exit(1);
2174
0
    free(ref);
2175
0
  }
2176
2177
0
  if (reinit && initial_branch)
2178
0
    warning(_("re-init: ignored --initial-branch=%s"),
2179
0
      initial_branch);
2180
2181
0
  strbuf_release(&err);
2182
0
  free(to_free);
2183
0
}
2184
2185
static int create_default_files(const char *template_path,
2186
        const char *original_git_dir,
2187
        const struct repository_format *fmt,
2188
        int init_shared_repository)
2189
0
{
2190
0
  struct stat st1;
2191
0
  struct strbuf buf = STRBUF_INIT;
2192
0
  char *path;
2193
0
  int reinit;
2194
0
  int filemode;
2195
0
  const char *work_tree = get_git_work_tree();
2196
2197
  /*
2198
   * First copy the templates -- we might have the default
2199
   * config file there, in which case we would want to read
2200
   * from it after installing.
2201
   *
2202
   * Before reading that config, we also need to clear out any cached
2203
   * values (since we've just potentially changed what's available on
2204
   * disk).
2205
   */
2206
0
  copy_templates(template_path);
2207
0
  git_config_clear();
2208
0
  reset_shared_repository();
2209
0
  git_config(git_default_config, NULL);
2210
2211
0
  reinit = is_reinit();
2212
2213
  /*
2214
   * We must make sure command-line options continue to override any
2215
   * values we might have just re-read from the config.
2216
   */
2217
0
  if (init_shared_repository != -1)
2218
0
    set_shared_repository(init_shared_repository);
2219
2220
0
  is_bare_repository_cfg = !work_tree;
2221
2222
  /*
2223
   * We would have created the above under user's umask -- under
2224
   * shared-repository settings, we would need to fix them up.
2225
   */
2226
0
  if (get_shared_repository()) {
2227
0
    adjust_shared_perm(get_git_dir());
2228
0
  }
2229
2230
0
  initialize_repository_version(fmt->hash_algo, fmt->ref_storage_format, 0);
2231
2232
  /* Check filemode trustability */
2233
0
  path = git_path_buf(&buf, "config");
2234
0
  filemode = TEST_FILEMODE;
2235
0
  if (TEST_FILEMODE && !lstat(path, &st1)) {
2236
0
    struct stat st2;
2237
0
    filemode = (!chmod(path, st1.st_mode ^ S_IXUSR) &&
2238
0
        !lstat(path, &st2) &&
2239
0
        st1.st_mode != st2.st_mode &&
2240
0
        !chmod(path, st1.st_mode));
2241
0
    if (filemode && !reinit && (st1.st_mode & S_IXUSR))
2242
0
      filemode = 0;
2243
0
  }
2244
0
  git_config_set("core.filemode", filemode ? "true" : "false");
2245
2246
0
  if (is_bare_repository())
2247
0
    git_config_set("core.bare", "true");
2248
0
  else {
2249
0
    git_config_set("core.bare", "false");
2250
    /* allow template config file to override the default */
2251
0
    if (log_all_ref_updates == LOG_REFS_UNSET)
2252
0
      git_config_set("core.logallrefupdates", "true");
2253
0
    if (needs_work_tree_config(original_git_dir, work_tree))
2254
0
      git_config_set("core.worktree", work_tree);
2255
0
  }
2256
2257
0
  if (!reinit) {
2258
    /* Check if symlink is supported in the work tree */
2259
0
    path = git_path_buf(&buf, "tXXXXXX");
2260
0
    if (!close(xmkstemp(path)) &&
2261
0
        !unlink(path) &&
2262
0
        !symlink("testing", path) &&
2263
0
        !lstat(path, &st1) &&
2264
0
        S_ISLNK(st1.st_mode))
2265
0
      unlink(path); /* good */
2266
0
    else
2267
0
      git_config_set("core.symlinks", "false");
2268
2269
    /* Check if the filesystem is case-insensitive */
2270
0
    path = git_path_buf(&buf, "CoNfIg");
2271
0
    if (!access(path, F_OK))
2272
0
      git_config_set("core.ignorecase", "true");
2273
0
    probe_utf8_pathname_composition();
2274
0
  }
2275
2276
0
  strbuf_release(&buf);
2277
0
  return reinit;
2278
0
}
2279
2280
static void create_object_directory(void)
2281
0
{
2282
0
  struct strbuf path = STRBUF_INIT;
2283
0
  size_t baselen;
2284
2285
0
  strbuf_addstr(&path, get_object_directory());
2286
0
  baselen = path.len;
2287
2288
0
  safe_create_dir(path.buf, 1);
2289
2290
0
  strbuf_setlen(&path, baselen);
2291
0
  strbuf_addstr(&path, "/pack");
2292
0
  safe_create_dir(path.buf, 1);
2293
2294
0
  strbuf_setlen(&path, baselen);
2295
0
  strbuf_addstr(&path, "/info");
2296
0
  safe_create_dir(path.buf, 1);
2297
2298
0
  strbuf_release(&path);
2299
0
}
2300
2301
static void separate_git_dir(const char *git_dir, const char *git_link)
2302
0
{
2303
0
  struct stat st;
2304
2305
0
  if (!stat(git_link, &st)) {
2306
0
    const char *src;
2307
2308
0
    if (S_ISREG(st.st_mode))
2309
0
      src = read_gitfile(git_link);
2310
0
    else if (S_ISDIR(st.st_mode))
2311
0
      src = git_link;
2312
0
    else
2313
0
      die(_("unable to handle file type %d"), (int)st.st_mode);
2314
2315
0
    if (rename(src, git_dir))
2316
0
      die_errno(_("unable to move %s to %s"), src, git_dir);
2317
0
    repair_worktrees(NULL, NULL);
2318
0
  }
2319
2320
0
  write_file(git_link, "gitdir: %s", git_dir);
2321
0
}
2322
2323
struct default_format_config {
2324
  int hash;
2325
  enum ref_storage_format ref_format;
2326
};
2327
2328
static int read_default_format_config(const char *key, const char *value,
2329
              const struct config_context *ctx UNUSED,
2330
              void *payload)
2331
0
{
2332
0
  struct default_format_config *cfg = payload;
2333
0
  char *str = NULL;
2334
0
  int ret;
2335
2336
0
  if (!strcmp(key, "init.defaultobjectformat")) {
2337
0
    ret = git_config_string(&str, key, value);
2338
0
    if (ret)
2339
0
      goto out;
2340
0
    cfg->hash = hash_algo_by_name(str);
2341
0
    if (cfg->hash == GIT_HASH_UNKNOWN)
2342
0
      warning(_("unknown hash algorithm '%s'"), str);
2343
0
    goto out;
2344
0
  }
2345
2346
0
  if (!strcmp(key, "init.defaultrefformat")) {
2347
0
    ret = git_config_string(&str, key, value);
2348
0
    if (ret)
2349
0
      goto out;
2350
0
    cfg->ref_format = ref_storage_format_by_name(str);
2351
0
    if (cfg->ref_format == REF_STORAGE_FORMAT_UNKNOWN)
2352
0
      warning(_("unknown ref storage format '%s'"), str);
2353
0
    goto out;
2354
0
  }
2355
2356
0
  ret = 0;
2357
0
out:
2358
0
  free(str);
2359
0
  return ret;
2360
0
}
2361
2362
static void repository_format_configure(struct repository_format *repo_fmt,
2363
          int hash, enum ref_storage_format ref_format)
2364
0
{
2365
0
  struct default_format_config cfg = {
2366
0
    .hash = GIT_HASH_UNKNOWN,
2367
0
    .ref_format = REF_STORAGE_FORMAT_UNKNOWN,
2368
0
  };
2369
0
  struct config_options opts = {
2370
0
    .respect_includes = 1,
2371
0
    .ignore_repo = 1,
2372
0
    .ignore_worktree = 1,
2373
0
  };
2374
0
  const char *env;
2375
2376
0
  config_with_options(read_default_format_config, &cfg, NULL, NULL, &opts);
2377
2378
  /*
2379
   * If we already have an initialized repo, don't allow the user to
2380
   * specify a different algorithm, as that could cause corruption.
2381
   * Otherwise, if the user has specified one on the command line, use it.
2382
   */
2383
0
  env = getenv(GIT_DEFAULT_HASH_ENVIRONMENT);
2384
0
  if (repo_fmt->version >= 0 && hash != GIT_HASH_UNKNOWN && hash != repo_fmt->hash_algo)
2385
0
    die(_("attempt to reinitialize repository with different hash"));
2386
0
  else if (hash != GIT_HASH_UNKNOWN)
2387
0
    repo_fmt->hash_algo = hash;
2388
0
  else if (env) {
2389
0
    int env_algo = hash_algo_by_name(env);
2390
0
    if (env_algo == GIT_HASH_UNKNOWN)
2391
0
      die(_("unknown hash algorithm '%s'"), env);
2392
0
    repo_fmt->hash_algo = env_algo;
2393
0
  } else if (cfg.hash != GIT_HASH_UNKNOWN) {
2394
0
    repo_fmt->hash_algo = cfg.hash;
2395
0
  }
2396
0
  repo_set_hash_algo(the_repository, repo_fmt->hash_algo);
2397
2398
0
  env = getenv("GIT_DEFAULT_REF_FORMAT");
2399
0
  if (repo_fmt->version >= 0 &&
2400
0
      ref_format != REF_STORAGE_FORMAT_UNKNOWN &&
2401
0
      ref_format != repo_fmt->ref_storage_format) {
2402
0
    die(_("attempt to reinitialize repository with different reference storage format"));
2403
0
  } else if (ref_format != REF_STORAGE_FORMAT_UNKNOWN) {
2404
0
    repo_fmt->ref_storage_format = ref_format;
2405
0
  } else if (env) {
2406
0
    ref_format = ref_storage_format_by_name(env);
2407
0
    if (ref_format == REF_STORAGE_FORMAT_UNKNOWN)
2408
0
      die(_("unknown ref storage format '%s'"), env);
2409
0
    repo_fmt->ref_storage_format = ref_format;
2410
0
  } else if (cfg.ref_format != REF_STORAGE_FORMAT_UNKNOWN) {
2411
0
    repo_fmt->ref_storage_format = cfg.ref_format;
2412
0
  }
2413
0
  repo_set_ref_storage_format(the_repository, repo_fmt->ref_storage_format);
2414
0
}
2415
2416
int init_db(const char *git_dir, const char *real_git_dir,
2417
      const char *template_dir, int hash,
2418
      enum ref_storage_format ref_storage_format,
2419
      const char *initial_branch,
2420
      int init_shared_repository, unsigned int flags)
2421
0
{
2422
0
  int reinit;
2423
0
  int exist_ok = flags & INIT_DB_EXIST_OK;
2424
0
  char *original_git_dir = real_pathdup(git_dir, 1);
2425
0
  struct repository_format repo_fmt = REPOSITORY_FORMAT_INIT;
2426
2427
0
  if (real_git_dir) {
2428
0
    struct stat st;
2429
2430
0
    if (!exist_ok && !stat(git_dir, &st))
2431
0
      die(_("%s already exists"), git_dir);
2432
2433
0
    if (!exist_ok && !stat(real_git_dir, &st))
2434
0
      die(_("%s already exists"), real_git_dir);
2435
2436
0
    set_git_dir(real_git_dir, 1);
2437
0
    git_dir = get_git_dir();
2438
0
    separate_git_dir(git_dir, original_git_dir);
2439
0
  }
2440
0
  else {
2441
0
    set_git_dir(git_dir, 1);
2442
0
    git_dir = get_git_dir();
2443
0
  }
2444
0
  startup_info->have_repository = 1;
2445
2446
  /*
2447
   * Check to see if the repository version is right.
2448
   * Note that a newly created repository does not have
2449
   * config file, so this will not fail.  What we are catching
2450
   * is an attempt to reinitialize new repository with an old tool.
2451
   */
2452
0
  check_repository_format(&repo_fmt);
2453
2454
0
  repository_format_configure(&repo_fmt, hash, ref_storage_format);
2455
2456
  /*
2457
   * Ensure `core.hidedotfiles` is processed. This must happen after we
2458
   * have set up the repository format such that we can evaluate
2459
   * includeIf conditions correctly in the case of re-initialization.
2460
   */
2461
0
  git_config(platform_core_config, NULL);
2462
2463
0
  safe_create_dir(git_dir, 0);
2464
2465
0
  reinit = create_default_files(template_dir, original_git_dir,
2466
0
              &repo_fmt, init_shared_repository);
2467
2468
0
  if (!(flags & INIT_DB_SKIP_REFDB))
2469
0
    create_reference_database(repo_fmt.ref_storage_format,
2470
0
            initial_branch, flags & INIT_DB_QUIET);
2471
0
  create_object_directory();
2472
2473
0
  if (get_shared_repository()) {
2474
0
    char buf[10];
2475
    /* We do not spell "group" and such, so that
2476
     * the configuration can be read by older version
2477
     * of git. Note, we use octal numbers for new share modes,
2478
     * and compatibility values for PERM_GROUP and
2479
     * PERM_EVERYBODY.
2480
     */
2481
0
    if (get_shared_repository() < 0)
2482
      /* force to the mode value */
2483
0
      xsnprintf(buf, sizeof(buf), "0%o", -get_shared_repository());
2484
0
    else if (get_shared_repository() == PERM_GROUP)
2485
0
      xsnprintf(buf, sizeof(buf), "%d", OLD_PERM_GROUP);
2486
0
    else if (get_shared_repository() == PERM_EVERYBODY)
2487
0
      xsnprintf(buf, sizeof(buf), "%d", OLD_PERM_EVERYBODY);
2488
0
    else
2489
0
      BUG("invalid value for shared_repository");
2490
0
    git_config_set("core.sharedrepository", buf);
2491
0
    git_config_set("receive.denyNonFastforwards", "true");
2492
0
  }
2493
2494
0
  if (!(flags & INIT_DB_QUIET)) {
2495
0
    int len = strlen(git_dir);
2496
2497
0
    if (reinit)
2498
0
      printf(get_shared_repository()
2499
0
             ? _("Reinitialized existing shared Git repository in %s%s\n")
2500
0
             : _("Reinitialized existing Git repository in %s%s\n"),
2501
0
             git_dir, len && git_dir[len-1] != '/' ? "/" : "");
2502
0
    else
2503
0
      printf(get_shared_repository()
2504
0
             ? _("Initialized empty shared Git repository in %s%s\n")
2505
0
             : _("Initialized empty Git repository in %s%s\n"),
2506
0
             git_dir, len && git_dir[len-1] != '/' ? "/" : "");
2507
0
  }
2508
2509
0
  clear_repository_format(&repo_fmt);
2510
0
  free(original_git_dir);
2511
0
  return 0;
2512
0
}