Merge branch 'nd/remove-ignore-env-field' into next
authorJunio C Hamano <gitster@pobox.com>
Thu, 15 Mar 2018 22:10:57 +0000 (15:10 -0700)
committerJunio C Hamano <gitster@pobox.com>
Thu, 15 Mar 2018 22:10:57 +0000 (15:10 -0700)
Code clean-up for the "repository" abstraction.

* nd/remove-ignore-env-field:
repository: delete ignore_env member
sha1_file.c: move delayed getenv(altdb) back to setup_git_env()
repository.c: delete dead functions
repository.c: move env-related setup code back to environment.c
repository: initialize the_repository in main()

cache.h
common-main.c
environment.c
repository.c
repository.h
setup.c
sha1_file.c
diff --git a/cache.h b/cache.h
index a61b2d3f0d79b0f56992e0343803811f5265d716..5593a657aaac8f85309cc5c2dcc4debee64f67d4 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -459,7 +459,7 @@ static inline enum object_type object_type(unsigned int mode)
  */
 extern const char * const local_repo_env[];
 
-extern void setup_git_env(void);
+extern void setup_git_env(const char *git_dir);
 
 /*
  * Returns true iff we have a configured git repository (either via
index 6a689007e7ce3fe08f148e8b82c0a1c618c513a5..7d716d5a5491ba6b3a596f2128c4f08253d1d364 100644 (file)
@@ -34,6 +34,8 @@ int main(int argc, const char **argv)
 
        git_setup_gettext();
 
+       initialize_the_repository();
+
        attr_start();
 
        git_extract_argv0_path(argv[0]);
index d6dd64662ce4d09296b61708b020a71eef3488f6..21565c3c525c64793282d8c3f029733615a87fc2 100644 (file)
@@ -13,6 +13,7 @@
 #include "refs.h"
 #include "fmt-merge-msg.h"
 #include "commit.h"
+#include "argv-array.h"
 
 int trust_executable_bit = 1;
 int trust_ctime = 1;
@@ -147,10 +148,35 @@ static char *expand_namespace(const char *raw_namespace)
        return strbuf_detach(&buf, NULL);
 }
 
-void setup_git_env(void)
+/*
+ * Wrapper of getenv() that returns a strdup value. This value is kept
+ * in argv to be freed later.
+ */
+static const char *getenv_safe(struct argv_array *argv, const char *name)
+{
+       const char *value = getenv(name);
+
+       if (!value)
+               return NULL;
+
+       argv_array_push(argv, value);
+       return argv->argv[argv->argc - 1];
+}
+
+void setup_git_env(const char *git_dir)
 {
        const char *shallow_file;
        const char *replace_ref_base;
+       struct set_gitdir_args args = { NULL };
+       struct argv_array to_free = ARGV_ARRAY_INIT;
+
+       args.commondir = getenv_safe(&to_free, GIT_COMMON_DIR_ENVIRONMENT);
+       args.object_dir = getenv_safe(&to_free, DB_ENVIRONMENT);
+       args.graft_file = getenv_safe(&to_free, GRAFT_ENVIRONMENT);
+       args.index_file = getenv_safe(&to_free, INDEX_ENVIRONMENT);
+       args.alternate_db = getenv_safe(&to_free, ALTERNATE_DB_ENVIRONMENT);
+       repo_set_gitdir(the_repository, git_dir, &args);
+       argv_array_clear(&to_free);
 
        if (getenv(NO_REPLACE_OBJECTS_ENVIRONMENT))
                check_replace_refs = 0;
@@ -300,8 +326,7 @@ int set_git_dir(const char *path)
 {
        if (setenv(GIT_DIR_ENVIRONMENT, path, 1))
                return error("Could not set GIT_DIR to '%s'", path);
-       repo_set_gitdir(the_repository, path);
-       setup_git_env();
+       setup_git_env(path);
        return 0;
 }
 
index 4ffbe9bc94edc18314cb49c945038e2f20a40922..62f52f47fcaed32c4f14a9f76eb1e66e13d4046a 100644 (file)
@@ -4,64 +4,68 @@
 #include "submodule-config.h"
 
 /* The main repository */
-static struct repository the_repo = {
-       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &the_index, &hash_algos[GIT_HASH_SHA1], 0, 0
-};
-struct repository *the_repository = &the_repo;
+static struct repository the_repo;
+struct repository *the_repository;
 
-static char *git_path_from_env(const char *envvar, const char *git_dir,
-                              const char *path, int fromenv)
+void initialize_the_repository(void)
 {
-       if (fromenv) {
-               const char *value = getenv(envvar);
-               if (value)
-                       return xstrdup(value);
-       }
+       the_repository = &the_repo;
 
-       return xstrfmt("%s/%s", git_dir, path);
+       the_repo.index = &the_index;
+       repo_set_hash_algo(&the_repo, GIT_HASH_SHA1);
 }
 
-static int find_common_dir(struct strbuf *sb, const char *gitdir, int fromenv)
+static void expand_base_dir(char **out, const char *in,
+                           const char *base_dir, const char *def_in)
 {
-       if (fromenv) {
-               const char *value = getenv(GIT_COMMON_DIR_ENVIRONMENT);
-               if (value) {
-                       strbuf_addstr(sb, value);
-                       return 1;
-               }
-       }
-
-       return get_common_dir_noenv(sb, gitdir);
+       free(*out);
+       if (in)
+               *out = xstrdup(in);
+       else
+               *out = xstrfmt("%s/%s", base_dir, def_in);
 }
 
-static void repo_setup_env(struct repository *repo)
+static void repo_set_commondir(struct repository *repo,
+                              const char *commondir)
 {
        struct strbuf sb = STRBUF_INIT;
 
-       repo->different_commondir = find_common_dir(&sb, repo->gitdir,
-                                                   !repo->ignore_env);
        free(repo->commondir);
+
+       if (commondir) {
+               repo->different_commondir = 1;
+               repo->commondir = xstrdup(commondir);
+               return;
+       }
+
+       repo->different_commondir = get_common_dir_noenv(&sb, repo->gitdir);
        repo->commondir = strbuf_detach(&sb, NULL);
-       free(repo->objectdir);
-       repo->objectdir = git_path_from_env(DB_ENVIRONMENT, repo->commondir,
-                                           "objects", !repo->ignore_env);
-       free(repo->graft_file);
-       repo->graft_file = git_path_from_env(GRAFT_ENVIRONMENT, repo->commondir,
-                                            "info/grafts", !repo->ignore_env);
-       free(repo->index_file);
-       repo->index_file = git_path_from_env(INDEX_ENVIRONMENT, repo->gitdir,
-                                            "index", !repo->ignore_env);
 }
 
-void repo_set_gitdir(struct repository *repo, const char *path)
+void repo_set_gitdir(struct repository *repo,
+                    const char *root,
+                    const struct set_gitdir_args *o)
 {
-       const char *gitfile = read_gitfile(path);
+       const char *gitfile = read_gitfile(root);
+       /*
+        * repo->gitdir is saved because the caller could pass "root"
+        * that also points to repo->gitdir. We want to keep it alive
+        * until after xstrdup(root). Then we can free it.
+        */
        char *old_gitdir = repo->gitdir;
 
-       repo->gitdir = xstrdup(gitfile ? gitfile : path);
-       repo_setup_env(repo);
-
+       repo->gitdir = xstrdup(gitfile ? gitfile : root);
        free(old_gitdir);
+
+       repo_set_commondir(repo, o->commondir);
+       expand_base_dir(&repo->objectdir, o->object_dir,
+                       repo->commondir, "objects");
+       free(repo->alternate_db);
+       repo->alternate_db = xstrdup_or_null(o->alternate_db);
+       expand_base_dir(&repo->graft_file, o->graft_file,
+                       repo->commondir, "info/grafts");
+       expand_base_dir(&repo->index_file, o->index_file,
+                       repo->gitdir, "index");
 }
 
 void repo_set_hash_algo(struct repository *repo, int hash_algo)
@@ -79,6 +83,7 @@ static int repo_init_gitdir(struct repository *repo, const char *gitdir)
        int error = 0;
        char *abspath = NULL;
        const char *resolved_gitdir;
+       struct set_gitdir_args args = { NULL };
 
        abspath = real_pathdup(gitdir, 0);
        if (!abspath) {
@@ -93,7 +98,7 @@ static int repo_init_gitdir(struct repository *repo, const char *gitdir)
                goto out;
        }
 
-       repo_set_gitdir(repo, resolved_gitdir);
+       repo_set_gitdir(repo, resolved_gitdir, &args);
 
 out:
        free(abspath);
@@ -128,13 +133,13 @@ static int read_and_verify_repository_format(struct repository_format *format,
  * Initialize 'repo' based on the provided 'gitdir'.
  * Return 0 upon success and a non-zero value upon failure.
  */
-int repo_init(struct repository *repo, const char *gitdir, const char *worktree)
+static int repo_init(struct repository *repo,
+                    const char *gitdir,
+                    const char *worktree)
 {
        struct repository_format format;
        memset(repo, 0, sizeof(*repo));
 
-       repo->ignore_env = 1;
-
        if (repo_init_gitdir(repo, gitdir))
                goto error;
 
@@ -210,6 +215,7 @@ void repo_clear(struct repository *repo)
        FREE_AND_NULL(repo->gitdir);
        FREE_AND_NULL(repo->commondir);
        FREE_AND_NULL(repo->objectdir);
+       FREE_AND_NULL(repo->alternate_db);
        FREE_AND_NULL(repo->graft_file);
        FREE_AND_NULL(repo->index_file);
        FREE_AND_NULL(repo->worktree);
index 0329e40c7f5e72dad3ba46328a8e3d6c29ed8e58..e7127baffba019812e458477a34a4d9a80a67cdc 100644 (file)
@@ -26,6 +26,9 @@ struct repository {
         */
        char *objectdir;
 
+       /* Path to extra alternate object database if not NULL */
+       char *alternate_db;
+
        /*
         * Path to the repository's graft file.
         * Cannot be NULL after initialization.
@@ -72,15 +75,6 @@ struct repository {
        const struct git_hash_algo *hash_algo;
 
        /* Configurations */
-       /*
-        * Bit used during initialization to indicate if repository state (like
-        * the location of the 'objectdir') should be read from the
-        * environment.  By default this bit will be set at the begining of
-        * 'repo_init()' so that all repositories will ignore the environment.
-        * The exception to this is 'the_repository', which doesn't go through
-        * the normal 'repo_init()' process.
-        */
-       unsigned ignore_env:1;
 
        /* Indicate if a repository has a different 'commondir' from 'gitdir' */
        unsigned different_commondir:1;
@@ -88,10 +82,20 @@ struct repository {
 
 extern struct repository *the_repository;
 
-extern void repo_set_gitdir(struct repository *repo, const char *path);
+struct set_gitdir_args {
+       const char *commondir;
+       const char *object_dir;
+       const char *graft_file;
+       const char *index_file;
+       const char *alternate_db;
+};
+
+extern void repo_set_gitdir(struct repository *repo,
+                           const char *root,
+                           const struct set_gitdir_args *optional);
 extern void repo_set_worktree(struct repository *repo, const char *path);
 extern void repo_set_hash_algo(struct repository *repo, int algo);
-extern int repo_init(struct repository *repo, const char *gitdir, const char *worktree);
+extern void initialize_the_repository(void);
 extern int repo_submodule_init(struct repository *submodule,
                               struct repository *superproject,
                               const char *path);
diff --git a/setup.c b/setup.c
index 72877796420b06213665f5d357decb202e71fa91..664453fcef7f3b75f56d000dc52f42a0aff42fb6 100644 (file)
--- a/setup.c
+++ b/setup.c
@@ -1116,8 +1116,7 @@ const char *setup_git_directory_gently(int *nongit_ok)
                        const char *gitdir = getenv(GIT_DIR_ENVIRONMENT);
                        if (!gitdir)
                                gitdir = DEFAULT_GIT_DIR_ENVIRONMENT;
-                       repo_set_gitdir(the_repository, gitdir);
-                       setup_git_env();
+                       setup_git_env(gitdir);
                }
                if (startup_info->have_repository)
                        repo_set_hash_algo(the_repository, repo_fmt.hash_algo);
index 1b94f39c4c5653b090d5dbecf0cf7a785b0556bb..89a8c1bad039a578742ad4dd95394379d0686db4 100644 (file)
@@ -665,15 +665,11 @@ int foreach_alt_odb(alt_odb_fn fn, void *cb)
 
 void prepare_alt_odb(void)
 {
-       const char *alt;
-
        if (alt_odb_tail)
                return;
 
-       alt = getenv(ALTERNATE_DB_ENVIRONMENT);
-
        alt_odb_tail = &alt_odb_list;
-       link_alt_odb_entries(alt, PATH_SEP, NULL, 0);
+       link_alt_odb_entries(the_repository->alternate_db, PATH_SEP, NULL, 0);
 
        read_info_alternates(get_object_directory(), 0);
 }