Permalink
Browse files

Improve config handling for diff,submodules,attrs

This adds support for a bunch of core.* settings that affect
diff and status, plus fixes up some incorrect implementations
of those settings from before.  Also, this cleans up the
handling of config settings in the new submodules code and
in the old attrs/ignore code.
  • Loading branch information...
arrbee committed Mar 30, 2012
1 parent bfc9ca5 commit 95dfb031f70601b12a9eb57229fd4aa9a51ddd54
Showing with 212 additions and 128 deletions.
  1. +1 −3 include/git2/submodule.h
  2. +44 −31 src/attr.c
  3. +5 −0 src/attr.h
  4. +2 −2 src/attr_file.c
  5. +0 −1 src/attr_file.h
  6. +43 −31 src/config.c
  7. +3 −0 src/config.h
  8. +80 −21 src/diff.c
  9. +9 −0 src/diff.h
  10. +5 −15 src/ignore.c
  11. +5 −0 src/repository.h
  12. +15 −24 src/submodule.c
View
@@ -22,7 +22,7 @@ GIT_BEGIN_DECL
typedef enum {
GIT_SUBMODULE_UPDATE_CHECKOUT = 0,
- GIT_SUBMOUDLE_UPDATE_REBASE = 1,
+ GIT_SUBMODULE_UPDATE_REBASE = 1,
GIT_SUBMODULE_UPDATE_MERGE = 2
} git_submodule_update_t;
@@ -80,8 +80,6 @@ GIT_EXTERN(int) git_submodule_foreach(
int (*callback)(const char *name, void *payload),
void *payload);
-#define GIT_SUBMODULE_HEAD "[internal]HEAD"
-
/**
* Lookup submodule information by name or path.
*
View
@@ -196,7 +196,8 @@ bool git_attr_cache__is_cached(git_repository *repo, const char *path)
const char *cache_key = path;
if (repo && git__prefixcmp(cache_key, git_repository_workdir(repo)) == 0)
cache_key += strlen(git_repository_workdir(repo));
- return (git_hashtable_lookup(repo->attrcache.files, cache_key) != NULL);
+ return (git_hashtable_lookup(
+ git_repository_attr_cache(repo)->files, cache_key) != NULL);
}
int git_attr_cache__lookup_or_create_file(
@@ -207,7 +208,7 @@ int git_attr_cache__lookup_or_create_file(
git_attr_file **file_ptr)
{
int error;
- git_attr_cache *cache = &repo->attrcache;
+ git_attr_cache *cache = git_repository_attr_cache(repo);
git_attr_file *file = NULL;
if ((file = git_hashtable_lookup(cache->files, key)) != NULL) {
@@ -293,7 +294,6 @@ static int collect_attr_files(
{
int error;
git_buf dir = GIT_BUF_INIT;
- git_config *cfg;
const char *workdir = git_repository_workdir(repo);
attr_walk_up_info info;
@@ -312,7 +312,8 @@ static int collect_attr_files(
* - $GIT_PREFIX/etc/gitattributes
*/
- error = push_attrs(repo, files, repo->path_repository, GIT_ATTR_FILE_INREPO);
+ error = push_attrs(
+ repo, files, git_repository_path(repo), GIT_ATTR_FILE_INREPO);
if (error < 0)
goto cleanup;
@@ -322,22 +323,18 @@ static int collect_attr_files(
if (error < 0)
goto cleanup;
- if (!(error = git_repository_config(&cfg, repo))) {
- const char *core_attribs = NULL;
- git_config_get_string(cfg, GIT_ATTR_CONFIG, &core_attribs);
- git_clearerror(); /* don't care if attributesfile is not set */
- if (core_attribs)
- error = push_attrs(repo, files, NULL, core_attribs);
- git_config_free(cfg);
+ if (git_repository_attr_cache(repo)->cfg_attr_file != NULL) {
+ error = push_attrs(
+ repo, files, NULL, git_repository_attr_cache(repo)->cfg_attr_file);
+ if (error < 0)
+ goto cleanup;
}
- if (!error) {
- error = git_futils_find_system_file(&dir, GIT_ATTR_FILE_SYSTEM);
- if (!error)
- error = push_attrs(repo, files, NULL, dir.ptr);
- else if (error == GIT_ENOTFOUND)
- error = 0;
- }
+ error = git_futils_find_system_file(&dir, GIT_ATTR_FILE_SYSTEM);
+ if (!error)
+ error = push_attrs(repo, files, NULL, dir.ptr);
+ else if (error == GIT_ENOTFOUND)
+ error = 0;
cleanup:
if (error < 0)
@@ -350,18 +347,34 @@ static int collect_attr_files(
int git_attr_cache__init(git_repository *repo)
{
- git_attr_cache *cache = &repo->attrcache;
+ git_attr_cache *cache = git_repository_attr_cache(repo);
+ git_config *cfg;
if (cache->initialized)
return 0;
+ /* cache config settings for attributes and ignores */
+ if (git_repository_config(&cfg, repo) < 0)
+ return -1;
+ if (git_config_get_string(cfg, GIT_ATTR_CONFIG, &cache->cfg_attr_file)) {
+ giterr_clear();
+ cache->cfg_attr_file = NULL;
+ }
+ if (git_config_get_string(cfg, GIT_IGNORE_CONFIG, &cache->cfg_excl_file)) {
+ giterr_clear();
+ cache->cfg_excl_file = NULL;
+ }
+ git_config_free(cfg);
+
+ /* allocate hashtable for attribute and ignore file contents */
if (cache->files == NULL) {
cache->files = git_hashtable_alloc(
8, git_hash__strhash_cb, git_hash__strcmp_cb);
if (!cache->files)
return -1;
}
+ /* allocate hashtable for attribute macros */
if (cache->macros == NULL) {
cache->macros = git_hashtable_alloc(
8, git_hash__strhash_cb, git_hash__strcmp_cb);
@@ -378,30 +391,30 @@ int git_attr_cache__init(git_repository *repo)
void git_attr_cache_flush(
git_repository *repo)
{
+ git_hashtable *table;
+
if (!repo)
return;
- if (repo->attrcache.files) {
+ if ((table = git_repository_attr_cache(repo)->files) != NULL) {
git_attr_file *file;
- GIT_HASHTABLE_FOREACH_VALUE(repo->attrcache.files, file,
- git_attr_file__free(file));
+ GIT_HASHTABLE_FOREACH_VALUE(table, file, git_attr_file__free(file));
+ git_hashtable_free(table);
- git_hashtable_free(repo->attrcache.files);
- repo->attrcache.files = NULL;
+ git_repository_attr_cache(repo)->files = NULL;
}
- if (repo->attrcache.macros) {
+ if ((table = git_repository_attr_cache(repo)->macros) != NULL) {
git_attr_rule *rule;
- GIT_HASHTABLE_FOREACH_VALUE(repo->attrcache.macros, rule,
- git_attr_rule__free(rule));
+ GIT_HASHTABLE_FOREACH_VALUE(table, rule, git_attr_rule__free(rule));
+ git_hashtable_free(table);
- git_hashtable_free(repo->attrcache.macros);
- repo->attrcache.macros = NULL;
+ git_repository_attr_cache(repo)->macros = NULL;
}
- repo->attrcache.initialized = 0;
+ git_repository_attr_cache(repo)->initialized = 0;
}
int git_attr_cache__insert_macro(git_repository *repo, git_attr_rule *macro)
@@ -411,5 +424,5 @@ int git_attr_cache__insert_macro(git_repository *repo, git_attr_rule *macro)
return 0;
return git_hashtable_insert(
- repo->attrcache.macros, macro->match.pattern, macro);
+ git_repository_attr_cache(repo)->macros, macro->match.pattern, macro);
}
View
@@ -9,10 +9,15 @@
#include "attr_file.h"
+#define GIT_ATTR_CONFIG "core.attributesfile"
+#define GIT_IGNORE_CONFIG "core.excludesfile"
+
typedef struct {
int initialized;
git_hashtable *files; /* hash path to git_attr_file of rules */
git_hashtable *macros; /* hash name to vector<git_attr_assignment> */
+ const char *cfg_attr_file; /* cached value of core.attributesfile */
+ const char *cfg_excl_file; /* cached value of core.excludesfile */
} git_attr_cache;
extern int git_attr_cache__init(git_repository *repo);
View
@@ -495,8 +495,8 @@ int git_attr_assignment__parse(
/* expand macros (if given a repo with a macro cache) */
if (repo != NULL && assign->value == git_attr__true) {
- git_attr_rule *macro =
- git_hashtable_lookup(repo->attrcache.macros, assign->name);
+ git_attr_rule *macro = git_hashtable_lookup(
+ git_repository_attr_cache(repo)->macros, assign->name);
if (macro != NULL) {
unsigned int i;
View
@@ -14,7 +14,6 @@
#define GIT_ATTR_FILE ".gitattributes"
#define GIT_ATTR_FILE_INREPO "info/attributes"
#define GIT_ATTR_FILE_SYSTEM "gitattributes"
-#define GIT_ATTR_CONFIG "core.attributesfile"
#define GIT_ATTR_FNMATCH_NEGATIVE (1U << 0)
#define GIT_ATTR_FNMATCH_DIRECTORY (1U << 1)
View
@@ -140,7 +140,7 @@ int git_config_add_file(git_config *cfg, git_config_file *file, int priority)
int git_config_foreach(git_config *cfg, int (*fn)(const char *, const char *, void *), void *data)
{
- int ret = GIT_SUCCESS;
+ int ret = 0;
unsigned int i;
file_internal *internal;
git_config_file *file;
@@ -206,20 +206,20 @@ int git_config_parse_bool(int *out, const char *value)
/* A missing value means true */
if (value == NULL) {
*out = 1;
- return GIT_SUCCESS;
+ return 0;
}
if (!strcasecmp(value, "true") ||
!strcasecmp(value, "yes") ||
!strcasecmp(value, "on")) {
*out = 1;
- return GIT_SUCCESS;
+ return 0;
}
if (!strcasecmp(value, "false") ||
!strcasecmp(value, "no") ||
!strcasecmp(value, "off")) {
*out = 0;
- return GIT_SUCCESS;
+ return 0;
}
return GIT_EINVALIDTYPE;
@@ -283,46 +283,58 @@ static int parse_int32(int32_t *out, const char *value)
/***********
* Getters
***********/
-int git_config_get_mapped(git_config *cfg, const char *name, git_cvar_map *maps, size_t map_n, int *out)
+int git_config_lookup_map_value(
+ git_cvar_map *maps, size_t map_n, const char *value, int *out)
{
size_t i;
- const char *value;
- int error;
- error = git_config_get_string(cfg, name, &value);
- if (error < GIT_SUCCESS)
- return error;
+ if (!value)
+ return GIT_ENOTFOUND;
for (i = 0; i < map_n; ++i) {
git_cvar_map *m = maps + i;
switch (m->cvar_type) {
- case GIT_CVAR_FALSE:
- case GIT_CVAR_TRUE: {
- int bool_val;
+ case GIT_CVAR_FALSE:
+ case GIT_CVAR_TRUE: {
+ int bool_val;
+
+ if (git_config_parse_bool(&bool_val, value) == 0 &&
+ bool_val == (int)m->cvar_type) {
+ *out = m->map_value;
+ return 0;
+ }
+ break;
+ }
- if (git_config_parse_bool(&bool_val, value) == 0 &&
- bool_val == (int)m->cvar_type) {
- *out = m->map_value;
- return 0;
- }
+ case GIT_CVAR_INT32:
+ if (parse_int32(out, value) == 0)
+ return 0;
+ break;
- break;
+ case GIT_CVAR_STRING:
+ if (strcasecmp(value, m->str_match) == 0) {
+ *out = m->map_value;
+ return 0;
}
+ break;
+ }
+ }
- case GIT_CVAR_INT32:
- if (parse_int32(out, value) == 0)
- return 0;
+ return GIT_ENOTFOUND;
+}
- break;
+int git_config_get_mapped(git_config *cfg, const char *name, git_cvar_map *maps, size_t map_n, int *out)
+{
+ const char *value;
+ int error;
- case GIT_CVAR_STRING:
- if (strcasecmp(value, m->str_match) == 0) {
- *out = m->map_value;
- return 0;
- }
- }
- }
+ error = git_config_get_string(cfg, name, &value);
+ if (error < 0)
+ return error;
+
+ if (!git_config_lookup_map_value(maps, map_n, value, out))
+ return 0;
giterr_set(GITERR_CONFIG,
"Failed to map the '%s' config variable with a valid value", name);
@@ -449,7 +461,7 @@ int git_config_set_multivar(git_config *cfg, const char *name, const char *regex
internal = git_vector_get(&cfg->files, i - 1);
file = internal->file;
ret = file->set_multivar(file, name, regexp, value);
- if (ret < GIT_SUCCESS && ret != GIT_ENOTFOUND)
+ if (ret < 0 && ret != GIT_ENOTFOUND)
return ret;
}
View
@@ -27,4 +27,7 @@ extern int git_config_find_system_r(git_buf *system_config_path);
extern int git_config_parse_bool(int *out, const char *bool_string);
+extern int git_config_lookup_map_value(
+ git_cvar_map *maps, size_t map_n, const char *value, int *out);
+
#endif
Oops, something went wrong.

0 comments on commit 95dfb03

Please sign in to comment.