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
commit 0873c393c7
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 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

View 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]);

View 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;
}

View 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);

View 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,24 @@ struct 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_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);

View File

@ -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);

View File

@ -668,15 +668,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);
}