repository.con commit submodule-config: store the_submodule_cache in the_repository (bf12fcd)
   1#include "cache.h"
   2#include "repository.h"
   3#include "config.h"
   4#include "submodule-config.h"
   5
   6/* The main repository */
   7static struct repository the_repo;
   8struct repository *the_repository = &the_repo;
   9
  10static char *git_path_from_env(const char *envvar, const char *git_dir,
  11                               const char *path, int fromenv)
  12{
  13        if (fromenv) {
  14                const char *value = getenv(envvar);
  15                if (value)
  16                        return xstrdup(value);
  17        }
  18
  19        return xstrfmt("%s/%s", git_dir, path);
  20}
  21
  22static int find_common_dir(struct strbuf *sb, const char *gitdir, int fromenv)
  23{
  24        if (fromenv) {
  25                const char *value = getenv(GIT_COMMON_DIR_ENVIRONMENT);
  26                if (value) {
  27                        strbuf_addstr(sb, value);
  28                        return 1;
  29                }
  30        }
  31
  32        return get_common_dir_noenv(sb, gitdir);
  33}
  34
  35static void repo_setup_env(struct repository *repo)
  36{
  37        struct strbuf sb = STRBUF_INIT;
  38
  39        repo->different_commondir = find_common_dir(&sb, repo->gitdir,
  40                                                    !repo->ignore_env);
  41        repo->commondir = strbuf_detach(&sb, NULL);
  42        repo->objectdir = git_path_from_env(DB_ENVIRONMENT, repo->commondir,
  43                                            "objects", !repo->ignore_env);
  44        repo->graft_file = git_path_from_env(GRAFT_ENVIRONMENT, repo->commondir,
  45                                             "info/grafts", !repo->ignore_env);
  46        repo->index_file = git_path_from_env(INDEX_ENVIRONMENT, repo->gitdir,
  47                                             "index", !repo->ignore_env);
  48}
  49
  50void repo_set_gitdir(struct repository *repo, const char *path)
  51{
  52        const char *gitfile = read_gitfile(path);
  53
  54        /*
  55         * NEEDSWORK: Eventually we want to be able to free gitdir and the rest
  56         * of the environment before reinitializing it again, but we have some
  57         * crazy code paths where we try to set gitdir with the current gitdir
  58         * and we don't want to free gitdir before copying the passed in value.
  59         */
  60        repo->gitdir = xstrdup(gitfile ? gitfile : path);
  61
  62        repo_setup_env(repo);
  63}
  64
  65/*
  66 * Attempt to resolve and set the provided 'gitdir' for repository 'repo'.
  67 * Return 0 upon success and a non-zero value upon failure.
  68 */
  69static int repo_init_gitdir(struct repository *repo, const char *gitdir)
  70{
  71        int ret = 0;
  72        int error = 0;
  73        char *abspath = NULL;
  74        const char *resolved_gitdir;
  75
  76        abspath = real_pathdup(gitdir, 0);
  77        if (!abspath) {
  78                ret = -1;
  79                goto out;
  80        }
  81
  82        /* 'gitdir' must reference the gitdir directly */
  83        resolved_gitdir = resolve_gitdir_gently(abspath, &error);
  84        if (!resolved_gitdir) {
  85                ret = -1;
  86                goto out;
  87        }
  88
  89        repo_set_gitdir(repo, resolved_gitdir);
  90
  91out:
  92        free(abspath);
  93        return ret;
  94}
  95
  96void repo_set_worktree(struct repository *repo, const char *path)
  97{
  98        repo->worktree = real_pathdup(path, 1);
  99}
 100
 101static int read_and_verify_repository_format(struct repository_format *format,
 102                                             const char *commondir)
 103{
 104        int ret = 0;
 105        struct strbuf sb = STRBUF_INIT;
 106
 107        strbuf_addf(&sb, "%s/config", commondir);
 108        read_repository_format(format, sb.buf);
 109        strbuf_reset(&sb);
 110
 111        if (verify_repository_format(format, &sb) < 0) {
 112                warning("%s", sb.buf);
 113                ret = -1;
 114        }
 115
 116        strbuf_release(&sb);
 117        return ret;
 118}
 119
 120/*
 121 * Initialize 'repo' based on the provided 'gitdir'.
 122 * Return 0 upon success and a non-zero value upon failure.
 123 */
 124int repo_init(struct repository *repo, const char *gitdir, const char *worktree)
 125{
 126        struct repository_format format;
 127        memset(repo, 0, sizeof(*repo));
 128
 129        repo->ignore_env = 1;
 130
 131        if (repo_init_gitdir(repo, gitdir))
 132                goto error;
 133
 134        if (read_and_verify_repository_format(&format, repo->commondir))
 135                goto error;
 136
 137        if (worktree)
 138                repo_set_worktree(repo, worktree);
 139
 140        return 0;
 141
 142error:
 143        repo_clear(repo);
 144        return -1;
 145}
 146
 147void repo_clear(struct repository *repo)
 148{
 149        free(repo->gitdir);
 150        repo->gitdir = NULL;
 151        free(repo->commondir);
 152        repo->commondir = NULL;
 153        free(repo->objectdir);
 154        repo->objectdir = NULL;
 155        free(repo->graft_file);
 156        repo->graft_file = NULL;
 157        free(repo->index_file);
 158        repo->index_file = NULL;
 159        free(repo->worktree);
 160        repo->worktree = NULL;
 161
 162        if (repo->config) {
 163                git_configset_clear(repo->config);
 164                free(repo->config);
 165                repo->config = NULL;
 166        }
 167
 168        if (repo->submodule_cache) {
 169                submodule_cache_free(repo->submodule_cache);
 170                repo->submodule_cache = NULL;
 171        }
 172
 173        if (repo->index) {
 174                discard_index(repo->index);
 175                free(repo->index);
 176                repo->index = NULL;
 177        }
 178}
 179
 180int repo_read_index(struct repository *repo)
 181{
 182        if (!repo->index)
 183                repo->index = xcalloc(1, sizeof(*repo->index));
 184        else
 185                discard_index(repo->index);
 186
 187        return read_index_from(repo->index, repo->index_file);
 188}