5
static int inside_git_dir = -1;
6
static int inside_work_tree = -1;
7
static int work_tree_config_is_bogus;
8
-static struct string_list unknown_extensions = STRING_LIST_INIT_DUP;
8
9
/*
10
* The input parameter must contain an absolute path, and it must already be
369
initialized = 1;
370
}
371
373
-static int check_repo_format(const char *var, const char *value, void *cb)
372
+static int check_repo_format(const char *var, const char *value, void *vdata)
373
{
374
+ struct repository_format *data = vdata;
375
const char *ext;
376
377
if (strcmp(var, "core.repositoryformatversion") == 0)
378
- repository_format_version = git_config_int(var, value);
378
+ data->version = git_config_int(var, value);
379
else if (skip_prefix(var, "extensions.", &ext)) {
380
/*
381
* record any known extensions here; otherwise,
385
if (!strcmp(ext, "noop"))
386
;
387
else if (!strcmp(ext, "preciousobjects"))
388
- repository_format_precious_objects = git_config_bool(var, value);
388
+ data->precious_objects = git_config_bool(var, value);
389
else
390
- string_list_append(&unknown_extensions, ext);
390
+ string_list_append(&data->unknown_extensions, ext);
391
}
392
return 0;
393
}
394
395
+static int read_repository_format_1(struct repository_format *, config_fn_t,
396
+ const char *);
397
+
398
static int check_repository_format_gently(const char *gitdir, int *nongit_ok)
399
{
400
struct strbuf sb = STRBUF_INIT;
398
- const char *repo_config;
401
+ struct strbuf err = STRBUF_INIT;
402
+ struct repository_format candidate;
403
config_fn_t fn;
400
- int ret = 0;
401
-
402
- string_list_clear(&unknown_extensions, 0);
404
405
if (get_common_dir(&sb, gitdir))
406
fn = check_repo_format;
407
else
408
fn = check_repository_format_version;
409
+
410
strbuf_addstr(&sb, "/config");
409
- repo_config = sb.buf;
411
+ read_repository_format_1(&candidate, fn, sb.buf);
412
+ strbuf_release(&sb);
413
414
/*
412
- * Ignore return value; for historical reasons, we must treat a missing
413
- * config file as a noop (git-init relies on this).
415
+ * For historical use of check_repository_format() in git-init,
416
+ * we treat a missing config as a silent "ok", even when nongit_ok
417
+ * is unset.
418
*/
415
- git_config_from_file(fn, repo_config, NULL);
416
- if (GIT_REPO_VERSION_READ < repository_format_version) {
417
- if (!nongit_ok)
418
- die ("Expected git repo version <= %d, found %d",
419
- GIT_REPO_VERSION_READ, repository_format_version);
420
- warning("Expected git repo version <= %d, found %d",
421
- GIT_REPO_VERSION_READ, repository_format_version);
422
- warning("Please upgrade Git");
423
- *nongit_ok = -1;
424
- ret = -1;
419
+ if (candidate.version < 0)
420
+ return 0;
421
+
422
+ if (verify_repository_format(&candidate, &err) < 0) {
423
+ if (nongit_ok) {
424
+ warning("%s", err.buf);
425
+ strbuf_release(&err);
426
+ *nongit_ok = -1;
427
+ return -1;
428
+ }
429
+ die("%s", err.buf);
430
}
431
427
- if (repository_format_version >= 1 && unknown_extensions.nr) {
432
+ repository_format_version = candidate.version;
433
+ repository_format_precious_objects = candidate.precious_objects;
434
+ string_list_clear(&candidate.unknown_extensions, 0);
435
+ if (candidate.is_bare != -1) {
436
+ is_bare_repository_cfg = candidate.is_bare;
437
+ if (is_bare_repository_cfg == 1)
438
+ inside_work_tree = -1;
439
+ }
440
+ if (candidate.work_tree) {
441
+ free(git_work_tree_cfg);
442
+ git_work_tree_cfg = candidate.work_tree;
443
+ inside_work_tree = -1;
444
+ }
445
+
446
+ return 0;
447
+}
448
+
449
+static int read_repository_format_1(struct repository_format *format,
450
+ config_fn_t fn, const char *path)
451
+{
452
+ memset(format, 0, sizeof(*format));
453
+ format->version = -1;
454
+ format->is_bare = -1;
455
+ string_list_init(&format->unknown_extensions, 1);
456
+ git_config_from_file(fn, path, format);
457
+ return format->version;
458
+}
459
+
460
+int read_repository_format(struct repository_format *format, const char *path)
461
+{
462
+ return read_repository_format_1(format, check_repository_format_version, path);
463
+}
464
+
465
+int verify_repository_format(const struct repository_format *format,
466
+ struct strbuf *err)
467
+{
468
+ if (GIT_REPO_VERSION_READ < format->version) {
469
+ strbuf_addf(err, "Expected git repo version <= %d, found %d",
470
+ GIT_REPO_VERSION_READ, format->version);
471
+ return -1;
472
+ }
473
+
474
+ if (format->version >= 1 && format->unknown_extensions.nr) {
475
int i;
476
430
- if (!nongit_ok)
431
- die("unknown repository extension: %s",
432
- unknown_extensions.items[0].string);
477
+ strbuf_addstr(err, "unknown repository extensions found:");
478
434
- for (i = 0; i < unknown_extensions.nr; i++)
435
- warning("unknown repository extension: %s",
436
- unknown_extensions.items[i].string);
437
- *nongit_ok = -1;
438
- ret = -1;
479
+ for (i = 0; i < format->unknown_extensions.nr; i++)
480
+ strbuf_addf(err, "\n\t%s",
481
+ format->unknown_extensions.items[i].string);
482
+ return -1;
483
}
484
441
- strbuf_release(&sb);
442
- return ret;
485
+ return 0;
486
}
487
488
/*
1001
1002
int check_repository_format_version(const char *var, const char *value, void *cb)
1003
{
1004
+ struct repository_format *data = cb;
1005
int ret = check_repo_format(var, value, cb);
1006
if (ret)
1007
return ret;
1008
if (strcmp(var, "core.bare") == 0) {
965
- is_bare_repository_cfg = git_config_bool(var, value);
966
- if (is_bare_repository_cfg == 1)
967
- inside_work_tree = -1;
1009
+ data->is_bare = git_config_bool(var, value);
1010
} else if (strcmp(var, "core.worktree") == 0) {
1011
if (!value)
1012
return config_error_nonbool(var);
971
- free(git_work_tree_cfg);
972
- git_work_tree_cfg = xstrdup(value);
973
- inside_work_tree = -1;
1013
+ data->work_tree = xstrdup(value);
1014
}
1015
return 0;
1016
}