Commit f2c25d18 by Vicent Martí

config: Implement a proper cvar cache

parent c63793ee
......@@ -223,8 +223,16 @@ int git_filter_add__crlf_to_odb(git_vector *filters, git_repository *repo, const
if (ca.crlf_action == GIT_CRLF_BINARY)
return 0;
if (ca.crlf_action == GIT_CRLF_GUESS && repo->filter_options.auto_crlf == GIT_AUTO_CRLF_FALSE)
return 0;
if (ca.crlf_action == GIT_CRLF_GUESS) {
int auto_crlf;
if ((error = git_repository__cvar(
&auto_crlf, repo, GIT_CVAR_AUTO_CRLF)) < GIT_SUCCESS)
return error;
if (auto_crlf == GIT_AUTO_CRLF_FALSE)
return 0;
}
/* If we're good, we create a new filter object and push it
* into the filters array */
......
......@@ -84,60 +84,10 @@ int git_text_is_binary(git_text_stats *stats)
return 0;
}
static int load_repository_settings(git_repository *repo)
{
static git_cvar_map map_eol[] = {
{GIT_CVAR_FALSE, NULL, GIT_EOL_UNSET},
{GIT_CVAR_STRING, "lf", GIT_EOL_LF},
{GIT_CVAR_STRING, "crlf", GIT_EOL_CRLF},
{GIT_CVAR_STRING, "native", GIT_EOL_NATIVE}
};
static git_cvar_map map_crlf[] = {
{GIT_CVAR_FALSE, NULL, GIT_AUTO_CRLF_FALSE},
{GIT_CVAR_TRUE, NULL, GIT_AUTO_CRLF_TRUE},
{GIT_CVAR_STRING, "input", GIT_AUTO_CRLF_INPUT}
};
git_config *config;
int error;
if (repo->filter_options.loaded)
return GIT_SUCCESS;
repo->filter_options.eol = GIT_EOL_DEFAULT;
repo->filter_options.auto_crlf = GIT_AUTO_CRLF_DEFAULT;
error = git_repository_config__weakptr(&config, repo);
if (error < GIT_SUCCESS)
return error;
error = git_config_get_mapped(
config, "core.eol", map_eol, ARRAY_SIZE(map_eol), &repo->filter_options.eol);
if (error < GIT_SUCCESS && error != GIT_ENOTFOUND)
return error;
error = git_config_get_mapped(
config, "core.auto_crlf", map_crlf, ARRAY_SIZE(map_crlf), &repo->filter_options.auto_crlf);
if (error < GIT_SUCCESS && error != GIT_ENOTFOUND)
return error;
repo->filter_options.loaded = 1;
return 0;
}
int git_filters_load(git_vector *filters, git_repository *repo, const char *path, int mode)
{
int error;
/* Make sure that the relevant settings from `gitconfig` have been
* cached on the repository struct to speed things up */
error = load_repository_settings(repo);
if (error < GIT_SUCCESS)
return error;
if (mode == GIT_FILTER_TO_ODB) {
/* Load the CRLF cleanup filter when writing to the ODB */
error = git_filter_add__crlf_to_odb(filters, repo, path);
......
......@@ -29,29 +29,8 @@ typedef enum {
GIT_CRLF_INPUT,
GIT_CRLF_CRLF,
GIT_CRLF_AUTO,
GIT_SAFE_CRLF_FALSE = 0,
GIT_SAFE_CRLF_FAIL = 1,
GIT_SAFE_CRLF_WARN = 2,
GIT_AUTO_CRLF_FALSE = 0,
GIT_AUTO_CRLF_TRUE = 1,
GIT_AUTO_CRLF_INPUT = -1,
GIT_AUTO_CRLF_DEFAULT = GIT_AUTO_CRLF_FALSE,
} git_crlf_t;
typedef enum {
GIT_EOL_UNSET,
GIT_EOL_CRLF,
GIT_EOL_LF,
#ifdef GIT_WIN32
GIT_EOL_NATIVE = GIT_EOL_CRLF,
#else
GIT_EOL_NATIVE = GIT_EOL_LF,
#endif
GIT_EOL_DEFAULT = GIT_EOL_NATIVE
} git_eol_t;
typedef struct {
/* NUL, CR, LF and CRLF counts */
unsigned int nul, cr, lf, crlf;
......
......@@ -43,6 +43,8 @@ static void drop_config(git_repository *repo)
git_config_free(repo->_config);
repo->_config = NULL;
}
git_repository__cvar_cache_clear(repo);
}
static void drop_index(git_repository *repo)
......@@ -111,6 +113,9 @@ static git_repository *repository_alloc(void)
return NULL;
}
/* set all the entries in the cvar cache to `unset` */
git_repository__cvar_cache_clear(repo);
return repo;
}
......
......@@ -26,6 +26,49 @@
#define GIT_DIR_MODE 0755
#define GIT_BARE_DIR_MODE 0777
/** Cvar cache identifiers */
typedef enum {
GIT_CVAR_AUTO_CRLF = 0, /* core.autocrlf */
GIT_CVAR_EOL, /* core.eol */
GIT_CVAR_CACHE_MAX
} git_cvar_cached;
/**
* CVAR value enumerations
*
* These are the values that are actually stored in the cvar cache, instead
* of their string equivalents. These values are internal and symbolic;
* make sure that none of them is set to `-1`, since that is the unique
* identifier for "not cached"
*/
typedef enum {
/* The value hasn't been loaded from the cache yet */
GIT_CVAR_NOT_CACHED = -1,
/* core.safecrlf: false, 'fail', 'warn' */
GIT_SAFE_CRLF_FALSE = 0,
GIT_SAFE_CRLF_FAIL = 1,
GIT_SAFE_CRLF_WARN = 2,
/* core.autocrlf: false, true, 'input; */
GIT_AUTO_CRLF_FALSE = 0,
GIT_AUTO_CRLF_TRUE = 1,
GIT_AUTO_CRLF_INPUT = 2,
GIT_AUTO_CRLF_DEFAULT = GIT_AUTO_CRLF_FALSE,
/* core.eol: unset, 'crlf', 'lf', 'native' */
GIT_EOL_UNSET = 0,
GIT_EOL_CRLF = 1,
GIT_EOL_LF = 2,
#ifdef GIT_WIN32
GIT_EOL_NATIVE = GIT_EOL_CRLF,
#else
GIT_EOL_NATIVE = GIT_EOL_LF,
#endif
GIT_EOL_DEFAULT = GIT_EOL_NATIVE
} git_cvar_value;
/** Base git object for inheritance */
struct git_object {
git_cached_obj cached;
git_repository *repo;
......@@ -47,11 +90,7 @@ struct git_repository {
unsigned is_bare:1;
unsigned int lru_counter;
struct {
int loaded;
int eol;
int auto_crlf;
} filter_options;
git_cvar_value cvar_cache[GIT_CVAR_CACHE_MAX];
};
/* fully free the object; internal method, do not
......@@ -61,8 +100,24 @@ void git_object__free(void *object);
int git_oid__parse(git_oid *oid, const char **buffer_out, const char *buffer_end, const char *header);
void git_oid__writebuf(git_buf *buf, const char *header, const git_oid *oid);
/*
* Weak pointers to repository internals.
*
* The returned pointers do not need to be freed. Do not keep
* permanent references to these (i.e. between API calls), since they may
* become invalidated if the user replaces a repository internal.
*/
int git_repository_config__weakptr(git_config **out, git_repository *repo);
int git_repository_odb__weakptr(git_odb **out, git_repository *repo);
int git_repository_index__weakptr(git_index **out, git_repository *repo);
/*
* CVAR cache
*
* Efficient access to the most used config variables of a repository.
* The cache is cleared everytime the config backend is replaced.
*/
int git_repository__cvar(int *out, git_repository *repo, git_cvar_cached cvar);
void git_repository__cvar_cache_clear(git_repository *repo);
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment