static void copy_templates(const char *template_dir) { struct strbuf path = STRBUF_INIT; struct strbuf template_path = STRBUF_INIT; size_t template_len; struct repository_format template_format = REPOSITORY_FORMAT_INIT; struct strbuf err = STRBUF_INIT; DIR *dir; char *to_free = NULL; if (!template_dir) template_dir = getenv(TEMPLATE_DIR_ENVIRONMENT); if (!template_dir) template_dir = init_db_template_dir; if (!template_dir) template_dir = to_free = system_path(DEFAULT_GIT_TEMPLATE_DIR); if (!template_dir[0]) { free(to_free); return; } strbuf_addstr(&template_path, template_dir); strbuf_complete(&template_path, '/'); template_len = template_path.len; dir = opendir(template_path.buf); if (!dir) { warning(_("templates not found in %s"), template_dir); goto free_return; } /* Make sure that template is from the correct vintage */ strbuf_addstr(&template_path, "config"); read_repository_format(&template_format, template_path.buf); strbuf_setlen(&template_path, template_len); /* * No mention of version at all is OK, but anything else should be * verified. */ if (template_format.version >= 0 && verify_repository_format(&template_format, &err) < 0) { warning(_("not copying templates from '%s': %s"), template_dir, err.buf); strbuf_release(&err); goto close_free_return; } strbuf_addstr(&path, get_git_common_dir()); strbuf_complete(&path, '/'); copy_templates_1(&path, &template_path, dir); close_free_return: closedir(dir); free_return: free(to_free); strbuf_release(&path); strbuf_release(&template_path); clear_repository_format(&template_format); }
static int check_repository_format_gently(const char *gitdir, int *nongit_ok) { struct strbuf sb = STRBUF_INIT; struct strbuf err = STRBUF_INIT; struct repository_format candidate; int has_common; has_common = get_common_dir(&sb, gitdir); strbuf_addstr(&sb, "/config"); read_repository_format(&candidate, sb.buf); strbuf_release(&sb); /* * For historical use of check_repository_format() in git-init, * we treat a missing config as a silent "ok", even when nongit_ok * is unset. */ if (candidate.version < 0) return 0; if (verify_repository_format(&candidate, &err) < 0) { if (nongit_ok) { warning("%s", err.buf); strbuf_release(&err); *nongit_ok = -1; return -1; } die("%s", err.buf); } repository_format_precious_objects = candidate.precious_objects; string_list_clear(&candidate.unknown_extensions, 0); if (!has_common) { if (candidate.is_bare != -1) { is_bare_repository_cfg = candidate.is_bare; if (is_bare_repository_cfg == 1) inside_work_tree = -1; } if (candidate.work_tree) { free(git_work_tree_cfg); git_work_tree_cfg = candidate.work_tree; inside_work_tree = -1; } } else { free(candidate.work_tree); } return 0; }
int submodule_uses_worktrees(const char *path) { char *submodule_gitdir; struct strbuf sb = STRBUF_INIT; DIR *dir; struct dirent *d; int ret = 0; struct repository_format format; submodule_gitdir = git_pathdup_submodule(path, "%s", ""); if (!submodule_gitdir) return 0; /* The env would be set for the superproject. */ get_common_dir_noenv(&sb, submodule_gitdir); free(submodule_gitdir); /* * The check below is only known to be good for repository format * version 0 at the time of writing this code. */ strbuf_addstr(&sb, "/config"); read_repository_format(&format, sb.buf); if (format.version != 0) { strbuf_release(&sb); return 1; } /* Replace config by worktrees. */ strbuf_setlen(&sb, sb.len - strlen("config")); strbuf_addstr(&sb, "worktrees"); /* See if there is any file inside the worktrees directory. */ dir = opendir(sb.buf); strbuf_release(&sb); if (!dir) return 0; while ((d = readdir(dir)) != NULL) { if (is_dot_or_dotdot(d->d_name)) continue; ret = 1; break; } closedir(dir); return ret; }
static int read_and_verify_repository_format(struct repository_format *format, const char *commondir) { int ret = 0; struct strbuf sb = STRBUF_INIT; strbuf_addf(&sb, "%s/config", commondir); read_repository_format(format, sb.buf); strbuf_reset(&sb); if (verify_repository_format(format, &sb) < 0) { warning("%s", sb.buf); ret = -1; } strbuf_release(&sb); return ret; }