Merge branch 'nd/remove-ignore-env-field'

Code clean-up for the "repository" abstraction.

* nd/remove-ignore-env-field:
  repository.h: add comment and clarify repo_set_gitdir
  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()
This commit is contained in:
Junio C Hamano
2018-04-10 16:28:20 +09:00
7 changed files with 101 additions and 65 deletions

View File

@ -459,7 +459,7 @@ static inline enum object_type object_type(unsigned int mode)
*/ */
extern const char * const local_repo_env[]; 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 * Returns true iff we have a configured git repository (either via

View File

@ -34,6 +34,8 @@ int main(int argc, const char **argv)
git_setup_gettext(); git_setup_gettext();
initialize_the_repository();
attr_start(); attr_start();
git_extract_argv0_path(argv[0]); git_extract_argv0_path(argv[0]);

View File

@ -13,6 +13,7 @@
#include "refs.h" #include "refs.h"
#include "fmt-merge-msg.h" #include "fmt-merge-msg.h"
#include "commit.h" #include "commit.h"
#include "argv-array.h"
int trust_executable_bit = 1; int trust_executable_bit = 1;
int trust_ctime = 1; int trust_ctime = 1;
@ -147,10 +148,35 @@ static char *expand_namespace(const char *raw_namespace)
return strbuf_detach(&buf, NULL); 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 *shallow_file;
const char *replace_ref_base; 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)) if (getenv(NO_REPLACE_OBJECTS_ENVIRONMENT))
check_replace_refs = 0; check_replace_refs = 0;
@ -300,8 +326,7 @@ int set_git_dir(const char *path)
{ {
if (setenv(GIT_DIR_ENVIRONMENT, path, 1)) if (setenv(GIT_DIR_ENVIRONMENT, path, 1))
return error("Could not set GIT_DIR to '%s'", path); return error("Could not set GIT_DIR to '%s'", path);
repo_set_gitdir(the_repository, path); setup_git_env(path);
setup_git_env();
return 0; return 0;
} }

View File

@ -4,64 +4,68 @@
#include "submodule-config.h" #include "submodule-config.h"
/* The main repository */ /* The main repository */
static struct repository the_repo = { 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;
};
struct repository *the_repository = &the_repo;
static char *git_path_from_env(const char *envvar, const char *git_dir, void initialize_the_repository(void)
const char *path, int fromenv)
{ {
if (fromenv) { the_repository = &the_repo;
const char *value = getenv(envvar);
if (value)
return xstrdup(value);
}
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) { free(*out);
const char *value = getenv(GIT_COMMON_DIR_ENVIRONMENT); if (in)
if (value) { *out = xstrdup(in);
strbuf_addstr(sb, value); else
return 1; *out = xstrfmt("%s/%s", base_dir, def_in);
}
}
return get_common_dir_noenv(sb, gitdir);
} }
static void repo_setup_env(struct repository *repo) static void repo_set_commondir(struct repository *repo,
const char *commondir)
{ {
struct strbuf sb = STRBUF_INIT; struct strbuf sb = STRBUF_INIT;
repo->different_commondir = find_common_dir(&sb, repo->gitdir,
!repo->ignore_env);
free(repo->commondir); 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); 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; char *old_gitdir = repo->gitdir;
repo->gitdir = xstrdup(gitfile ? gitfile : path); repo->gitdir = xstrdup(gitfile ? gitfile : root);
repo_setup_env(repo);
free(old_gitdir); 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) 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; int error = 0;
char *abspath = NULL; char *abspath = NULL;
const char *resolved_gitdir; const char *resolved_gitdir;
struct set_gitdir_args args = { NULL };
abspath = real_pathdup(gitdir, 0); abspath = real_pathdup(gitdir, 0);
if (!abspath) { if (!abspath) {
@ -93,7 +98,7 @@ static int repo_init_gitdir(struct repository *repo, const char *gitdir)
goto out; goto out;
} }
repo_set_gitdir(repo, resolved_gitdir); repo_set_gitdir(repo, resolved_gitdir, &args);
out: out:
free(abspath); free(abspath);
@ -128,13 +133,13 @@ static int read_and_verify_repository_format(struct repository_format *format,
* Initialize 'repo' based on the provided 'gitdir'. * Initialize 'repo' based on the provided 'gitdir'.
* Return 0 upon success and a non-zero value upon failure. * 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; struct repository_format format;
memset(repo, 0, sizeof(*repo)); memset(repo, 0, sizeof(*repo));
repo->ignore_env = 1;
if (repo_init_gitdir(repo, gitdir)) if (repo_init_gitdir(repo, gitdir))
goto error; goto error;
@ -210,6 +215,7 @@ void repo_clear(struct repository *repo)
FREE_AND_NULL(repo->gitdir); FREE_AND_NULL(repo->gitdir);
FREE_AND_NULL(repo->commondir); FREE_AND_NULL(repo->commondir);
FREE_AND_NULL(repo->objectdir); FREE_AND_NULL(repo->objectdir);
FREE_AND_NULL(repo->alternate_db);
FREE_AND_NULL(repo->graft_file); FREE_AND_NULL(repo->graft_file);
FREE_AND_NULL(repo->index_file); FREE_AND_NULL(repo->index_file);
FREE_AND_NULL(repo->worktree); FREE_AND_NULL(repo->worktree);

View File

@ -26,6 +26,9 @@ struct repository {
*/ */
char *objectdir; char *objectdir;
/* Path to extra alternate object database if not NULL */
char *alternate_db;
/* /*
* Path to the repository's graft file. * Path to the repository's graft file.
* Cannot be NULL after initialization. * Cannot be NULL after initialization.
@ -72,15 +75,6 @@ struct repository {
const struct git_hash_algo *hash_algo; const struct git_hash_algo *hash_algo;
/* Configurations */ /* 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' */ /* Indicate if a repository has a different 'commondir' from 'gitdir' */
unsigned different_commondir:1; unsigned different_commondir:1;
@ -88,10 +82,24 @@ struct repository {
extern struct repository *the_repository; extern struct repository *the_repository;
extern void repo_set_gitdir(struct repository *repo, const char *path); /*
* Define a custom repository layout. Any field can be NULL, which
* will default back to the path according to the default layout.
*/
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 *extra_args);
extern void repo_set_worktree(struct repository *repo, const char *path); extern void repo_set_worktree(struct repository *repo, const char *path);
extern void repo_set_hash_algo(struct repository *repo, int algo); 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, extern int repo_submodule_init(struct repository *submodule,
struct repository *superproject, struct repository *superproject,
const char *path); const char *path);

View File

@ -1116,8 +1116,7 @@ const char *setup_git_directory_gently(int *nongit_ok)
const char *gitdir = getenv(GIT_DIR_ENVIRONMENT); const char *gitdir = getenv(GIT_DIR_ENVIRONMENT);
if (!gitdir) if (!gitdir)
gitdir = DEFAULT_GIT_DIR_ENVIRONMENT; gitdir = DEFAULT_GIT_DIR_ENVIRONMENT;
repo_set_gitdir(the_repository, gitdir); setup_git_env(gitdir);
setup_git_env();
} }
if (startup_info->have_repository) if (startup_info->have_repository)
repo_set_hash_algo(the_repository, repo_fmt.hash_algo); repo_set_hash_algo(the_repository, repo_fmt.hash_algo);

View File

@ -668,15 +668,11 @@ int foreach_alt_odb(alt_odb_fn fn, void *cb)
void prepare_alt_odb(void) void prepare_alt_odb(void)
{ {
const char *alt;
if (alt_odb_tail) if (alt_odb_tail)
return; return;
alt = getenv(ALTERNATE_DB_ENVIRONMENT);
alt_odb_tail = &alt_odb_list; 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); read_info_alternates(get_object_directory(), 0);
} }