summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/git2/diff.h8
-rw-r--r--src/attr.c16
-rw-r--r--src/config.c181
-rw-r--r--src/config.h21
-rw-r--r--src/config_cache.c22
-rw-r--r--src/config_file.c13
-rw-r--r--src/diff.c39
-rw-r--r--src/diff_driver.c39
-rw-r--r--src/diff_tform.c35
-rw-r--r--src/merge.c17
-rw-r--r--src/notes.c15
-rw-r--r--src/remote.c63
-rw-r--r--src/repository.c40
-rw-r--r--src/submodule.c14
-rw-r--r--src/transports/local.c3
15 files changed, 267 insertions, 259 deletions
diff --git a/include/git2/diff.h b/include/git2/diff.h
index 315cc1215..d6919393a 100644
--- a/include/git2/diff.h
+++ b/include/git2/diff.h
@@ -468,7 +468,7 @@ typedef int (*git_diff_line_cb)(
* Flags to control the behavior of diff rename/copy detection.
*/
typedef enum {
- /** Obey `diff.renames`. This is overridden by any other GIT_DIFF_FIND_ALL flag. */
+ /** Obey `diff.renames`. Overridden by any other GIT_DIFF_FIND_... flag. */
GIT_DIFF_FIND_BY_CONFIG = 0,
/** Look for renames? (`--find-renames`) */
@@ -577,9 +577,9 @@ typedef struct {
unsigned int version;
/**
- * Combination of git_diff_find_t values (default FIND_BY_CONFIG).
- * Note that if you don't explicitly set this, `diff.renames` could be set
- * to false, resulting in `git_diff_find_similar` doing nothing.
+ * Combination of git_diff_find_t values (default GIT_DIFF_FIND_BY_CONFIG).
+ * NOTE: if you don't explicitly set this, `diff.renames` could be set
+ * to false, resulting in `git_diff_find_similar` doing nothing.
*/
uint32_t flags;
diff --git a/src/attr.c b/src/attr.c
index 98a328a55..51895b7ac 100644
--- a/src/attr.c
+++ b/src/attr.c
@@ -603,11 +603,15 @@ static int attr_cache__lookup_path(
{
git_buf buf = GIT_BUF_INIT;
int error;
- const char *cfgval = NULL;
+ const git_config_entry *entry = NULL;
*out = NULL;
- if (!(error = git_config_get_string(&cfgval, cfg, key))) {
+ if ((error = git_config__lookup_entry(&entry, cfg, key, false)) < 0)
+ return error;
+
+ if (entry) {
+ const char *cfgval = entry->value;
/* expand leading ~/ as needed */
if (cfgval && cfgval[0] == '~' && cfgval[1] == '/' &&
@@ -616,13 +620,9 @@ static int attr_cache__lookup_path(
else if (cfgval)
*out = git__strdup(cfgval);
- } else if (error == GIT_ENOTFOUND) {
- giterr_clear();
- error = 0;
-
- if (!git_futils_find_xdg_file(&buf, fallback))
- *out = git_buf_detach(&buf);
}
+ else if (!git_futils_find_xdg_file(&buf, fallback))
+ *out = git_buf_detach(&buf);
git_buf_free(&buf);
diff --git a/src/config.c b/src/config.c
index 0d9471383..227adbc9b 100644
--- a/src/config.c
+++ b/src/config.c
@@ -620,6 +620,78 @@ int git_config_set_string(git_config *cfg, const char *name, const char *value)
/***********
* Getters
***********/
+
+static int config_error_notfound(const char *name)
+{
+ giterr_set(GITERR_CONFIG, "Config value '%s' was not found", name);
+ return GIT_ENOTFOUND;
+}
+
+enum {
+ GET_ALL_ERRORS = 0,
+ GET_NO_MISSING = 1,
+ GET_NO_ERRORS = 2
+};
+
+static int get_entry(
+ const git_config_entry **out,
+ const git_config *cfg,
+ const char *name,
+ bool normalize_name,
+ int want_errors)
+{
+ int res = GIT_ENOTFOUND;
+ const char *key = name;
+ char *normalized = NULL;
+ size_t i;
+ file_internal *internal;
+
+ *out = NULL;
+
+ if (normalize_name) {
+ if ((res = git_config__normalize_name(name, &normalized)) < 0)
+ goto cleanup;
+ key = normalized;
+ }
+
+ git_vector_foreach(&cfg->files, i, internal) {
+ if (!internal || !internal->file)
+ continue;
+
+ res = internal->file->get(internal->file, key, out);
+ if (res != GIT_ENOTFOUND)
+ break;
+ }
+
+ git__free(normalized);
+
+cleanup:
+ if (res == GIT_ENOTFOUND)
+ res = (want_errors > GET_ALL_ERRORS) ? 0 : config_error_notfound(name);
+ else if (res && (want_errors == GET_NO_ERRORS)) {
+ giterr_clear();
+ res = 0;
+ }
+
+ return res;
+}
+
+int git_config_get_entry(
+ const git_config_entry **out, const git_config *cfg, const char *name)
+{
+ return get_entry(out, cfg, name, true, GET_ALL_ERRORS);
+}
+
+int git_config__lookup_entry(
+ const git_config_entry **out,
+ const git_config *cfg,
+ const char *key,
+ bool no_errors)
+{
+ return get_entry(
+ out, cfg, key, false, no_errors ? GET_NO_ERRORS : GET_NO_MISSING);
+}
+
int git_config_get_mapped(
int *out,
const git_config *cfg,
@@ -627,116 +699,91 @@ int git_config_get_mapped(
const git_cvar_map *maps,
size_t map_n)
{
- const char *value;
+ const git_config_entry *entry;
int ret;
- if ((ret = git_config_get_string(&value, cfg, name)) < 0)
+ if ((ret = get_entry(&entry, cfg, name, true, GET_ALL_ERRORS)) < 0)
return ret;
- return git_config_lookup_map_value(out, maps, map_n, value);
+ return git_config_lookup_map_value(out, maps, map_n, entry->value);
}
int git_config_get_int64(int64_t *out, const git_config *cfg, const char *name)
{
- const char *value;
+ const git_config_entry *entry;
int ret;
- if ((ret = git_config_get_string(&value, cfg, name)) < 0)
+ if ((ret = get_entry(&entry, cfg, name, true, GET_ALL_ERRORS)) < 0)
return ret;
- return git_config_parse_int64(out, value);
+ return git_config_parse_int64(out, entry->value);
}
int git_config_get_int32(int32_t *out, const git_config *cfg, const char *name)
{
- const char *value;
+ const git_config_entry *entry;
int ret;
- if ((ret = git_config_get_string(&value, cfg, name)) < 0)
+ if ((ret = get_entry(&entry, cfg, name, true, GET_ALL_ERRORS)) < 0)
return ret;
- return git_config_parse_int32(out, value);
+ return git_config_parse_int32(out, entry->value);
}
-static int get_string_at_file(const char **out, const git_config_backend *file, const char *name)
+int git_config_get_bool(int *out, const git_config *cfg, const char *name)
{
const git_config_entry *entry;
- int res;
+ int ret;
- res = file->get(file, name, &entry);
- if (!res)
- *out = entry->value;
+ if ((ret = get_entry(&entry, cfg, name, true, GET_ALL_ERRORS)) < 0)
+ return ret;
- return res;
+ return git_config_parse_bool(out, entry->value);
}
-static int config_error_notfound(const char *name)
+int git_config_get_string(
+ const char **out, const git_config *cfg, const char *name)
{
- giterr_set(GITERR_CONFIG, "Config value '%s' was not found", name);
- return GIT_ENOTFOUND;
+ const git_config_entry *entry;
+ int ret = get_entry(&entry, cfg, name, true, GET_ALL_ERRORS);
+ *out = !ret ? (entry->value ? entry->value : "") : NULL;
+ return ret;
}
-static int get_string(const char **out, const git_config *cfg, const char *name)
+const char *git_config__get_string_force(
+ const git_config *cfg, const char *key, const char *fallback_value)
{
- file_internal *internal;
- unsigned int i;
- int res;
-
- git_vector_foreach(&cfg->files, i, internal) {
- if (!internal || !internal->file)
- continue;
-
- res = get_string_at_file(out, internal->file, name);
- if (res != GIT_ENOTFOUND)
- return res;
- }
-
- return config_error_notfound(name);
+ const git_config_entry *entry;
+ get_entry(&entry, cfg, key, false, GET_NO_ERRORS);
+ return (entry && entry->value) ? entry->value : fallback_value;
}
-int git_config_get_bool(int *out, const git_config *cfg, const char *name)
+int git_config__get_bool_force(
+ const git_config *cfg, const char *key, int fallback_value)
{
- const char *value = NULL;
- int ret;
-
- if ((ret = get_string(&value, cfg, name)) < 0)
- return ret;
-
- return git_config_parse_bool(out, value);
-}
+ int val = fallback_value;
+ const git_config_entry *entry;
-int git_config_get_string(const char **out, const git_config *cfg, const char *name)
-{
- int ret;
- const char *str = NULL;
+ get_entry(&entry, cfg, key, false, GET_NO_ERRORS);
- if ((ret = get_string(&str, cfg, name)) < 0)
- return ret;
+ if (entry && git_config_parse_bool(&val, entry->value) < 0)
+ giterr_clear();
- *out = str == NULL ? "" : str;
- return 0;
+ return val;
}
-int git_config_get_entry(const git_config_entry **out, const git_config *cfg, const char *name)
+int git_config__get_int_force(
+ const git_config *cfg, const char *key, int fallback_value)
{
- file_internal *internal;
- unsigned int i;
- git_config_backend *file;
- int ret;
-
- *out = NULL;
+ int32_t val = (int32_t)fallback_value;
+ const git_config_entry *entry;
- git_vector_foreach(&cfg->files, i, internal) {
- if (!internal || !internal->file)
- continue;
- file = internal->file;
+ get_entry(&entry, cfg, key, false, GET_NO_ERRORS);
- ret = file->get(file, name, out);
- if (ret != GIT_ENOTFOUND)
- return ret;
- }
+ if (entry && git_config_parse_int32(&val, entry->value) < 0)
+ giterr_clear();
- return config_error_notfound(name);
+ return (int)val;
}
int git_config_get_multivar_foreach(
@@ -1070,7 +1117,7 @@ int git_config_parse_int64(int64_t *out, const char *value)
const char *num_end;
int64_t num;
- if (git__strtol64(&num, value, &num_end, 0) < 0)
+ if (!value || git__strtol64(&num, value, &num_end, 0) < 0)
goto fail_parse;
switch (*num_end) {
diff --git a/src/config.h b/src/config.h
index 01e8465cc..3cd888c88 100644
--- a/src/config.h
+++ b/src/config.h
@@ -51,5 +51,26 @@ extern int git_config_file__ondisk(git_config_backend **out, const char *path);
extern int git_config__normalize_name(const char *in, char **out);
+/* internal only: does not normalize key and sets out to NULL if not found */
+extern int git_config__lookup_entry(
+ const git_config_entry **out,
+ const git_config *cfg,
+ const char *key,
+ bool no_errors);
+
+/*
+ * Lookup functions that cannot fail. These functions look up a config
+ * value and return a fallback value if the value is missing or if any
+ * failures occur while trying to access the value.
+ */
+
+extern const char *git_config__get_string_force(
+ const git_config *cfg, const char *key, const char *fallback_value);
+
+extern int git_config__get_bool_force(
+ const git_config *cfg, const char *key, int fallback_value);
+
+extern int git_config__get_int_force(
+ const git_config *cfg, const char *key, int fallback_value);
#endif
diff --git a/src/config_cache.c b/src/config_cache.c
index 6808521a3..ec75d1501 100644
--- a/src/config_cache.c
+++ b/src/config_cache.c
@@ -78,22 +78,22 @@ int git_repository__cvar(int *out, git_repository *repo, git_cvar_cached cvar)
struct map_data *data = &_cvar_maps[(int)cvar];
git_config *config;
int error;
+ const git_config_entry *entry;
- error = git_repository_config__weakptr(&config, repo);
- if (error < 0)
+ if ((error = git_repository_config__weakptr(&config, repo)) < 0)
return error;
- if (data->maps)
- error = git_config_get_mapped(
- out, config, data->cvar_name, data->maps, data->map_count);
- else
- error = git_config_get_bool(out, config, data->cvar_name);
+ git_config__lookup_entry(&entry, config, data->cvar_name, false);
- if (error == GIT_ENOTFOUND) {
- giterr_clear();
+ if (!entry)
*out = data->default_value;
- }
- else if (error < 0)
+ else if (data->maps)
+ error = git_config_lookup_map_value(
+ out, data->maps, data->map_count, entry->value);
+ else
+ error = git_config_parse_bool(out, entry->value);
+
+ if (error < 0)
return error;
repo->cvar_cache[(int)cvar] = *out;
diff --git a/src/config_file.c b/src/config_file.c
index 15c8de49c..0971aa7b0 100644
--- a/src/config_file.c
+++ b/src/config_file.c
@@ -404,20 +404,12 @@ static int config_set(git_config_backend *cfg, const char *name, const char *val
/*
* Internal function that actually gets the value in string form
*/
-static int config_get(const git_config_backend *cfg, const char *name, const git_config_entry **out)
+static int config_get(const git_config_backend *cfg, const char *key, const git_config_entry **out)
{
diskfile_backend *b = (diskfile_backend *)cfg;
- char *key;
- khiter_t pos;
- int error;
+ khiter_t pos = git_strmap_lookup_index(b->values, key);
cvar_t *var;
- if ((error = git_config__normalize_name(name, &key)) < 0)
- return error;
-
- pos = git_strmap_lookup_index(b->values, key);
- git__free(key);
-
/* no error message; the config system will write one */
if (!git_strmap_valid_index(b->values, pos))
return GIT_ENOTFOUND;
@@ -427,7 +419,6 @@ static int config_get(const git_config_backend *cfg, const char *name, const git
var = var->next;
*out = var->entry;
-
return 0;
}
diff --git a/src/diff.c b/src/diff.c
index 4c33a0213..53a8f4638 100644
--- a/src/diff.c
+++ b/src/diff.c
@@ -304,26 +304,6 @@ bool git_diff_delta__should_skip(
}
-static int config_bool(git_config *cfg, const char *name, int defvalue)
-{
- int val = defvalue;
-
- if (git_config_get_bool(&val, cfg, name) < 0)
- giterr_clear();
-
- return val;
-}
-
-static int config_int(git_config *cfg, const char *name, int defvalue)
-{
- int val = defvalue;
-
- if (git_config_get_int32(&val, cfg, name) < 0)
- giterr_clear();
-
- return val;
-}
-
static const char *diff_mnemonic_prefix(
git_iterator_type_t type, bool left_side)
{
@@ -422,8 +402,8 @@ static int diff_list_apply_options(
diff->opts.flags |= GIT_DIFF_INCLUDE_UNTRACKED;
/* load config values that affect diff behavior */
- if (git_repository_config__weakptr(&cfg, repo) < 0)
- return -1;
+ if ((val = git_repository_config__weakptr(&cfg, repo)) < 0)
+ return val;
if (!git_repository__cvar(&val, repo, GIT_CVAR_SYMLINKS) && val)
diff->diffcaps = diff->diffcaps | GIT_DIFFCAPS_HAS_SYMLINKS;
@@ -445,7 +425,7 @@ static int diff_list_apply_options(
/* If not given explicit `opts`, check `diff.xyz` configs */
if (!opts) {
- int context = config_int(cfg, "diff.context", 3);
+ int context = git_config__get_int_force(cfg, "diff.context", 3);
diff->opts.context_lines = context >= 0 ? (uint16_t)context : 3;
/* add other defaults here */
@@ -460,12 +440,11 @@ static int diff_list_apply_options(
/* if ignore_submodules not explicitly set, check diff config */
if (diff->opts.ignore_submodules <= 0) {
- const char *str;
+ const git_config_entry *entry;
+ git_config__lookup_entry(&entry, cfg, "diff.ignoresubmodules", true);
- if (git_config_get_string(&str , cfg, "diff.ignoreSubmodules") < 0)
- giterr_clear();
- else if (str != NULL &&
- git_submodule_parse_ignore(&diff->opts.ignore_submodules, str) < 0)
+ if (entry && git_submodule_parse_ignore(
+ &diff->opts.ignore_submodules, entry->value) < 0)
giterr_clear();
}
@@ -474,9 +453,9 @@ static int diff_list_apply_options(
const char *use_old = DIFF_OLD_PREFIX_DEFAULT;
const char *use_new = DIFF_NEW_PREFIX_DEFAULT;
- if (config_bool(cfg, "diff.noprefix", 0)) {
+ if (git_config__get_bool_force(cfg, "diff.noprefix", 0))
use_old = use_new = "";
- } else if (config_bool(cfg, "diff.mnemonicprefix", 0)) {
+ else if (git_config__get_bool_force(cfg, "diff.mnemonicprefix", 0)) {
use_old = diff_mnemonic_prefix(diff->old_src, true);
use_new = diff_mnemonic_prefix(diff->new_src, false);
}
diff --git a/src/diff_driver.c b/src/diff_driver.c
index bd5a8fbd9..167c0cc5a 100644
--- a/src/diff_driver.c
+++ b/src/diff_driver.c
@@ -14,6 +14,7 @@
#include "strmap.h"
#include "map.h"
#include "buf_text.h"
+#include "config.h"
#include "repository.h"
GIT__USE_STRMAP;
@@ -130,14 +131,14 @@ static git_diff_driver_registry *git_repository_driver_registry(
static int git_diff_driver_load(
git_diff_driver **out, git_repository *repo, const char *driver_name)
{
- int error = 0, bval;
+ int error = 0;
git_diff_driver_registry *reg;
git_diff_driver *drv;
size_t namelen = strlen(driver_name);
khiter_t pos;
git_config *cfg;
git_buf name = GIT_BUF_INIT;
- const char *val;
+ const git_config_entry *ce;
bool found_driver = false;
reg = git_repository_driver_registry(repo);
@@ -164,23 +165,21 @@ static int git_diff_driver_load(
if ((error = git_buf_printf(&name, "diff.%s.binary", driver_name)) < 0)
goto done;
- if ((error = git_config_get_string(&val, cfg, name.ptr)) < 0) {
- if (error != GIT_ENOTFOUND)
- goto done;
- /* diff.<driver>.binary unspecified, so just continue */
- giterr_clear();
- } else if (git_config_parse_bool(&bval, val) < 0) {
- /* TODO: warn that diff.<driver>.binary has invalid value */
- giterr_clear();
- } else if (bval) {
+
+ switch (git_config__get_bool_force(cfg, name.ptr, -1)) {
+ case true:
/* if diff.<driver>.binary is true, just return the binary driver */
*out = &global_drivers[DIFF_DRIVER_BINARY];
goto done;
- } else {
+ case false:
/* if diff.<driver>.binary is false, force binary checks off */
/* but still may have custom function context patterns, etc. */
drv->binary_flags = GIT_DIFF_FORCE_TEXT;
found_driver = true;
+ break;
+ default:
+ /* diff.<driver>.binary unspecified, so just continue */
+ break;
}
/* TODO: warn if diff.<name>.command or diff.<name>.textconv are set */
@@ -211,16 +210,16 @@ static int git_diff_driver_load(
git_buf_truncate(&name, namelen + strlen("diff.."));
git_buf_put(&name, "wordregex", strlen("wordregex"));
- if ((error = git_config_get_string(&val, cfg, name.ptr)) < 0) {
- if (error != GIT_ENOTFOUND)
- goto done;
- giterr_clear(); /* no diff.<driver>.wordregex, so just continue */
- } else if ((error = regcomp(&drv->word_pattern, val, REG_EXTENDED)) != 0) {
- /* TODO: warning about bad regex instead of failure */
- error = giterr_set_regex(&drv->word_pattern, error);
+ if ((error = git_config__lookup_entry(&ce, cfg, name.ptr, false)) < 0)
goto done;
- } else {
+ if (!ce || !ce->value)
+ /* no diff.<driver>.wordregex, so just continue */;
+ else if (!(error = regcomp(&drv->word_pattern, ce->value, REG_EXTENDED)))
found_driver = true;
+ else {
+ /* TODO: warn about bad regex instead of failure */
+ error = giterr_set_regex(&drv->word_pattern, error);
+ goto done;
}
/* TODO: look up diff.<driver>.algorithm to turn on minimal / patience
diff --git a/src/diff_tform.c b/src/diff_tform.c
index 702e43bd3..2f94b2e77 100644
--- a/src/diff_tform.c
+++ b/src/diff_tform.c
@@ -13,6 +13,7 @@
#include "hashsig.h"
#include "path.h"
#include "fileops.h"
+#include "config.h"
static git_diff_delta *diff_delta__dup(
const git_diff_delta *d, git_pool *pool)
@@ -290,19 +291,16 @@ static int normalize_find_opts(
if (!given ||
(given->flags & GIT_DIFF_FIND_ALL) == GIT_DIFF_FIND_BY_CONFIG)
{
- const char *val = NULL;
-
- if (git_config_get_string(&val, cfg, "diff.renames") < 0)
- giterr_clear();
- else if (val) {
- int boolval;
- if (!git__parse_bool(&boolval, val) && !boolval) {
- /* do nothing */
- } else if (!strcasecmp(val, "copies") || !strcasecmp(val, "copy"))
- opts->flags |= (GIT_DIFF_FIND_RENAMES | GIT_DIFF_FIND_COPIES);
- else
- opts->flags |= GIT_DIFF_FIND_RENAMES;
- }
+ const char *rule =
+ git_config__get_string_force(cfg, "diff.renames", "true");
+ int boolval;
+
+ if (!git__parse_bool(&boolval, rule) && !boolval)
+ /* don't set FIND_RENAMES if bool value is false */;
+ else if (!strcasecmp(rule, "copies") || !strcasecmp(rule, "copy"))
+ opts->flags |= GIT_DIFF_FIND_RENAMES | GIT_DIFF_FIND_COPIES;
+ else
+ opts->flags |= GIT_DIFF_FIND_RENAMES;
}
/* some flags imply others */
@@ -343,14 +341,11 @@ static int normalize_find_opts(
#undef USE_DEFAULT
if (!opts->rename_limit) {
- int32_t limit = 0;
-
- opts->rename_limit = DEFAULT_RENAME_LIMIT;
+ opts->rename_limit = git_config__get_int_force(
+ cfg, "diff.renamelimit", DEFAULT_RENAME_LIMIT);
- if (git_config_get_int32(&limit, cfg, "diff.renameLimit") < 0)
- giterr_clear();
- else if (limit > 0)
- opts->rename_limit = limit;
+ if (opts->rename_limit <= 0)
+ opts->rename_limit = DEFAULT_RENAME_LIMIT;
}
/* assign the internal metric with whitespace flag as payload */
diff --git a/src/merge.c b/src/merge.c
index 45387d4ad..e552b037b 100644
--- a/src/merge.c
+++ b/src/merge.c
@@ -26,6 +26,7 @@
#include "oid.h"
#include "index.h"
#include "filebuf.h"
+#include "config.h"
#include "git2/types.h"
#include "git2/repository.h"
@@ -1396,19 +1397,13 @@ static int merge_tree_normalize_opts(
}
if (!opts->target_limit) {
- int32_t limit = 0;
+ int limit = git_config__get_int_force(cfg, "merge.renamelimit", 0);
- opts->target_limit = GIT_MERGE_TREE_TARGET_LIMIT;
+ if (!limit)
+ limit = git_config__get_int_force(cfg, "diff.renamelimit", 0);
- if (git_config_get_int32(&limit, cfg, "merge.renameLimit") < 0) {
- giterr_clear();
-
- if (git_config_get_int32(&limit, cfg, "diff.renameLimit") < 0)
- giterr_clear();
- }
-
- if (limit > 0)
- opts->target_limit = limit;
+ opts->target_limit = (limit <= 0) ?
+ GIT_MERGE_TREE_TARGET_LIMIT : (unsigned int)limit;
}
/* assign the internal metric with whitespace flag as payload */
diff --git a/src/notes.c b/src/notes.c
index beace1b50..d8ed32f82 100644
--- a/src/notes.c
+++ b/src/notes.c
@@ -378,20 +378,11 @@ cleanup:
static int note_get_default_ref(const char **out, git_repository *repo)
{
- int ret;
git_config *cfg;
+ int ret = git_repository_config__weakptr(&cfg, repo);
- *out = NULL;
-
- if (git_repository_config__weakptr(&cfg, repo) < 0)
- return -1;
-
- ret = git_config_get_string(out, cfg, "core.notesRef");
- if (ret == GIT_ENOTFOUND) {
- giterr_clear();
- *out = GIT_NOTES_DEFAULT_REF;
- return 0;
- }
+ *out = (ret != 0) ? NULL : git_config__get_string_force(
+ cfg, "core.notesref", GIT_NOTES_DEFAULT_REF);
return ret;
}
diff --git a/src/remote.c b/src/remote.c
index 3d890a5f1..6f86a4b57 100644
--- a/src/remote.c
+++ b/src/remote.c
@@ -45,7 +45,7 @@ static int add_refspec(git_remote *remote, const char *string, bool is_fetch)
static int download_tags_value(git_remote *remote, git_config *cfg)
{
- const char *val;
+ const git_config_entry *ce;
git_buf buf = GIT_BUF_INIT;
int error;
@@ -53,16 +53,14 @@ static int download_tags_value(git_remote *remote, git_config *cfg)
if (git_buf_printf(&buf, "remote.%s.tagopt", remote->name) < 0)
return -1;
- error = git_config_get_string(&val, cfg, git_buf_cstr(&buf));
+ error = git_config__lookup_entry(&ce, cfg, git_buf_cstr(&buf), false);
git_buf_free(&buf);
- if (!error && !strcmp(val, "--no-tags"))
- remote->download_tags = GIT_REMOTE_DOWNLOAD_TAGS_NONE;
- else if (!error && !strcmp(val, "--tags"))
- remote->download_tags = GIT_REMOTE_DOWNLOAD_TAGS_ALL;
- if (error == GIT_ENOTFOUND) {
- giterr_clear();
- error = 0;
+ if (!error && ce && ce->value) {
+ if (!strcmp(ce->value, "--no-tags"))
+ remote->download_tags = GIT_REMOTE_DOWNLOAD_TAGS_NONE;
+ else if (!strcmp(ce->value, "--tags"))
+ remote->download_tags = GIT_REMOTE_DOWNLOAD_TAGS_ALL;
}
return error;
@@ -104,12 +102,7 @@ static int get_check_cert(int *out, git_repository *repo)
if ((error = git_repository_config__weakptr(&cfg, repo)) < 0)
return error;
- if ((error = git_config_get_bool(out, cfg, "http.sslVerify")) == 0)
- return 0;
- else if (error != GIT_ENOTFOUND)
- return error;
-
- giterr_clear();
+ *out = git_config__get_bool_force(cfg, "http.sslverify", 1);
return 0;
}
@@ -493,7 +486,7 @@ int git_remote_save(const git_remote *remote)
}
if (error < 0) {
git_buf_free(&buf);
- return -1;
+ return error;
}
}
@@ -667,7 +660,8 @@ int git_remote_ls(const git_remote_head ***out, size_t *size, git_remote *remote
int git_remote__get_http_proxy(git_remote *remote, bool use_ssl, char **proxy_url)
{
git_config *cfg;
- const char *val;
+ const git_config_entry *ce;
+ const char *val = NULL;
int error;
assert(remote);
@@ -684,44 +678,39 @@ int git_remote__get_http_proxy(git_remote *remote, bool use_ssl, char **proxy_ur
* to least specific. */
/* remote.<name>.proxy config setting */
- if (remote->name && 0 != *(remote->name)) {
+ if (remote->name && remote->name[0]) {
git_buf buf = GIT_BUF_INIT;
if ((error = git_buf_printf(&buf, "remote.%s.proxy", remote->name)) < 0)
return error;
- if ((error = git_config_get_string(&val, cfg, git_buf_cstr(&buf))) == 0 &&
- val && ('\0' != *val)) {
- git_buf_free(&buf);
+ error = git_config__lookup_entry(&ce, cfg, git_buf_cstr(&buf), false);
+ git_buf_free(&buf);
- *proxy_url = git__strdup(val);
- GITERR_CHECK_ALLOC(*proxy_url);
- return 0;
- } else if (error != GIT_ENOTFOUND)
+ if (error < 0)
return error;
- giterr_clear();
- git_buf_free(&buf);
+ if (ce && ce->value) {
+ val = ce->value;
+ goto found;
+ }
}
/* http.proxy config setting */
- if ((error = git_config_get_string(&val, cfg, "http.proxy")) == 0 &&
- val && ('\0' != *val)) {
- *proxy_url = git__strdup(val);
- GITERR_CHECK_ALLOC(*proxy_url);
- return 0;
- } else if (error != GIT_ENOTFOUND)
+ if ((error = git_config__lookup_entry(&ce, cfg, "http.proxy", false)) < 0)
return error;
-
- giterr_clear();
+ if (ce && ce->value) {
+ val = ce->value;
+ goto found;
+ }
/* HTTP_PROXY / HTTPS_PROXY environment variables */
val = use_ssl ? getenv("HTTPS_PROXY") : getenv("HTTP_PROXY");
- if (val && ('\0' != *val)) {
+found:
+ if (val && val[0]) {
*proxy_url = git__strdup(val);
GITERR_CHECK_ALLOC(*proxy_url);
- return 0;
}
return 0;
diff --git a/src/repository.c b/src/repository.c
index 278c0384e..443744504 100644
--- a/src/repository.c
+++ b/src/repository.c
@@ -186,39 +186,37 @@ static int load_workdir(git_repository *repo, git_buf *parent_path)
{
int error;
git_config *config;
- const char *worktree;
- git_buf worktree_buf = GIT_BUF_INIT;
+ const git_config_entry *ce;
+ git_buf worktree = GIT_BUF_INIT;
if (repo->is_bare)
return 0;
- if (git_repository_config__weakptr(&config, repo) < 0)
- return -1;
+ if ((error = git_repository_config__weakptr(&config, repo)) < 0)
+ return error;
- error = git_config_get_string(&worktree, config, "core.worktree");
- if (!error && worktree != NULL) {
- error = git_path_prettify_dir(
- &worktree_buf, worktree, repo->path_repository);
- if (error < 0)
+ if ((error = git_config__lookup_entry(
+ &ce, config, "core.worktree", false)) < 0)
+ return error;
+
+ if (ce && ce->value) {
+ if ((error = git_path_prettify_dir(
+ &worktree, ce->value, repo->path_repository)) < 0)
return error;
- repo->workdir = git_buf_detach(&worktree_buf);
+
+ repo->workdir = git_buf_detach(&worktree);
}
- else if (error != GIT_ENOTFOUND)
- return error;
+ else if (parent_path && git_path_isdir(parent_path->ptr))
+ repo->workdir = git_buf_detach(parent_path);
else {
- giterr_clear();
+ if (git_path_dirname_r(&worktree, repo->path_repository) < 0 ||
+ git_path_to_dir(&worktree) < 0)
+ return -1;
- if (parent_path && git_path_isdir(parent_path->ptr))
- repo->workdir = git_buf_detach(parent_path);
- else {
- git_path_dirname_r(&worktree_buf, repo->path_repository);
- git_path_to_dir(&worktree_buf);
- repo->workdir = git_buf_detach(&worktree_buf);
- }
+ repo->workdir = git_buf_detach(&worktree);
}
GITERR_CHECK_ALLOC(repo->workdir);
-
return 0;
}
diff --git a/src/submodule.c b/src/submodule.c
index 586494fed..1e3d07911 100644
--- a/src/submodule.c
+++ b/src/submodule.c
@@ -1468,7 +1468,7 @@ static int submodule_update_config(
int error;
git_config *config;
git_buf key = GIT_BUF_INIT;
- const char *old = NULL;
+ const git_config_entry *ce = NULL;
assert(submodule);
@@ -1480,14 +1480,16 @@ static int submodule_update_config(
if (error < 0)
goto cleanup;
- if (git_config_get_string(&old, config, key.ptr) < 0)
- giterr_clear();
+ if ((error = git_config__lookup_entry(&ce, config, key.ptr, false)) < 0)
+ goto cleanup;
- if (!old && only_existing)
+ if (!ce && only_existing)
+ goto cleanup;
+ if (ce && !overwrite)
goto cleanup;
- if (old && !overwrite)
+ if (value && ce && ce->value && !strcmp(ce->value, value))
goto cleanup;
- if ((!old && !value) || (old && value && strcmp(old, value) == 0))
+ if (!value && (!ce || !ce->value))
goto cleanup;
if (!value)
diff --git a/src/transports/local.c b/src/transports/local.c
index 4502f0202..f09e797ce 100644
--- a/src/transports/local.c
+++ b/src/transports/local.c
@@ -250,8 +250,9 @@ static int local_negotiate_fetch(
git_oid_cpy(&rhead->loid, git_object_id(obj));
else if (error != GIT_ENOTFOUND)
return error;
+ else
+ giterr_clear();
git_object_free(obj);
- giterr_clear();
}
return 0;