mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-28 00:25:29 +00:00
Add config read fns with controlled error behavior
This adds `git_config__lookup_entry` which will look up a key in a config and return either the entry or NULL if the key was not present. Optionally, it can either suppress all errors or can return them (although not finding the key is not an error for this function). Unlike other accessors, this does not normalize the config key string, so it must only be used when the key is known to be in normalized form (i.e. all lower-case before the first dot and after the last dot, with no invalid characters). This also adds three high-level helper functions to look up config values with no errors and a fallback value. The three functions are for string, bool, and int values, and will resort to the fallback value for any error that arises. They are: * `git_config__get_string_force` * `git_config__get_bool_force` * `git_config__get_int_force` None of them normalize the config `key` either, so they can only be used for internal cases where the key is known to be in normal format.
This commit is contained in:
parent
0eedacb06a
commit
9f77b3f6f5
@ -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;
|
||||
|
||||
|
16
src/attr.c
16
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);
|
||||
|
||||
|
213
src/config.c
213
src/config.c
@ -620,55 +620,6 @@ int git_config_set_string(git_config *cfg, const char *name, const char *value)
|
||||
/***********
|
||||
* Getters
|
||||
***********/
|
||||
int git_config_get_mapped(
|
||||
int *out,
|
||||
const git_config *cfg,
|
||||
const char *name,
|
||||
const git_cvar_map *maps,
|
||||
size_t map_n)
|
||||
{
|
||||
const char *value;
|
||||
int ret;
|
||||
|
||||
if ((ret = git_config_get_string(&value, cfg, name)) < 0)
|
||||
return ret;
|
||||
|
||||
return git_config_lookup_map_value(out, maps, map_n, value);
|
||||
}
|
||||
|
||||
int git_config_get_int64(int64_t *out, const git_config *cfg, const char *name)
|
||||
{
|
||||
const char *value;
|
||||
int ret;
|
||||
|
||||
if ((ret = git_config_get_string(&value, cfg, name)) < 0)
|
||||
return ret;
|
||||
|
||||
return git_config_parse_int64(out, value);
|
||||
}
|
||||
|
||||
int git_config_get_int32(int32_t *out, const git_config *cfg, const char *name)
|
||||
{
|
||||
const char *value;
|
||||
int ret;
|
||||
|
||||
if ((ret = git_config_get_string(&value, cfg, name)) < 0)
|
||||
return ret;
|
||||
|
||||
return git_config_parse_int32(out, value);
|
||||
}
|
||||
|
||||
static int get_string_at_file(const char **out, const git_config_backend *file, const char *name)
|
||||
{
|
||||
const git_config_entry *entry;
|
||||
int res;
|
||||
|
||||
res = file->get(file, name, &entry);
|
||||
if (!res)
|
||||
*out = entry->value;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int config_error_notfound(const char *name)
|
||||
{
|
||||
@ -676,67 +627,163 @@ static int config_error_notfound(const char *name)
|
||||
return GIT_ENOTFOUND;
|
||||
}
|
||||
|
||||
static int get_string(const char **out, const git_config *cfg, const char *name)
|
||||
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;
|
||||
unsigned int i;
|
||||
int res;
|
||||
|
||||
*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 = get_string_at_file(out, internal->file, name);
|
||||
res = internal->file->get(internal->file, key, out);
|
||||
if (res != GIT_ENOTFOUND)
|
||||
return res;
|
||||
break;
|
||||
}
|
||||
|
||||
return config_error_notfound(name);
|
||||
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,
|
||||
const char *name,
|
||||
const git_cvar_map *maps,
|
||||
size_t map_n)
|
||||
{
|
||||
const git_config_entry *entry;
|
||||
int ret;
|
||||
|
||||
if ((ret = get_entry(&entry, cfg, name, true, GET_ALL_ERRORS)) < 0)
|
||||
return ret;
|
||||
|
||||
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 git_config_entry *entry;
|
||||
int ret;
|
||||
|
||||
if ((ret = get_entry(&entry, cfg, name, true, GET_ALL_ERRORS)) < 0)
|
||||
return ret;
|
||||
|
||||
return git_config_parse_int64(out, entry->value);
|
||||
}
|
||||
|
||||
int git_config_get_int32(int32_t *out, const git_config *cfg, const char *name)
|
||||
{
|
||||
const git_config_entry *entry;
|
||||
int ret;
|
||||
|
||||
if ((ret = get_entry(&entry, cfg, name, true, GET_ALL_ERRORS)) < 0)
|
||||
return ret;
|
||||
|
||||
return git_config_parse_int32(out, entry->value);
|
||||
}
|
||||
|
||||
int git_config_get_bool(int *out, const git_config *cfg, const char *name)
|
||||
{
|
||||
const char *value = NULL;
|
||||
const git_config_entry *entry;
|
||||
int ret;
|
||||
|
||||
if ((ret = get_string(&value, cfg, name)) < 0)
|
||||
if ((ret = get_entry(&entry, cfg, name, true, GET_ALL_ERRORS)) < 0)
|
||||
return ret;
|
||||
|
||||
return git_config_parse_bool(out, value);
|
||||
return git_config_parse_bool(out, entry->value);
|
||||
}
|
||||
|
||||
int git_config_get_string(const char **out, const git_config *cfg, const char *name)
|
||||
int git_config_get_string(
|
||||
const char **out, const git_config *cfg, const char *name)
|
||||
{
|
||||
int ret;
|
||||
const char *str = NULL;
|
||||
|
||||
if ((ret = get_string(&str, cfg, name)) < 0)
|
||||
return ret;
|
||||
|
||||
*out = str == NULL ? "" : str;
|
||||
return 0;
|
||||
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;
|
||||
}
|
||||
|
||||
int git_config_get_entry(const git_config_entry **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;
|
||||
git_config_backend *file;
|
||||
int ret;
|
||||
const git_config_entry *entry;
|
||||
get_entry(&entry, cfg, key, false, GET_NO_ERRORS);
|
||||
return (entry && entry->value) ? entry->value : fallback_value;
|
||||
}
|
||||
|
||||
*out = NULL;
|
||||
int git_config__get_bool_force(
|
||||
const git_config *cfg, const char *key, int fallback_value)
|
||||
{
|
||||
int val = 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_bool(&val, entry->value) < 0)
|
||||
giterr_clear();
|
||||
|
||||
return config_error_notfound(name);
|
||||
return val;
|
||||
}
|
||||
|
||||
int git_config__get_int_force(
|
||||
const git_config *cfg, const char *key, int fallback_value)
|
||||
{
|
||||
int32_t val = (int32_t)fallback_value;
|
||||
const git_config_entry *entry;
|
||||
|
||||
get_entry(&entry, cfg, key, false, GET_NO_ERRORS);
|
||||
|
||||
if (entry && git_config_parse_int32(&val, entry->value) < 0)
|
||||
giterr_clear();
|
||||
|
||||
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) {
|
||||
|
21
src/config.h
21
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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
39
src/diff.c
39
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);
|
||||
}
|
||||
|
@ -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 */
|
||||
if ((error = git_config__lookup_entry(&ce, cfg, name.ptr, false)) < 0)
|
||||
goto done;
|
||||
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;
|
||||
} else {
|
||||
found_driver = true;
|
||||
}
|
||||
|
||||
/* TODO: look up diff.<driver>.algorithm to turn on minimal / patience
|
||||
|
@ -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;
|
||||
const char *rule =
|
||||
git_config__get_string_force(cfg, "diff.renames", "true");
|
||||
int boolval;
|
||||
|
||||
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;
|
||||
}
|
||||
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 = git_config__get_int_force(
|
||||
cfg, "diff.renamelimit", DEFAULT_RENAME_LIMIT);
|
||||
|
||||
opts->rename_limit = 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 */
|
||||
|
17
src/merge.c
17
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 */
|
||||
|
15
src/notes.c
15
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;
|
||||
}
|
||||
|
63
src/remote.c
63
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;
|
||||
|
@ -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;
|
||||
|
||||
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)
|
||||
return error;
|
||||
repo->workdir = git_buf_detach(&worktree_buf);
|
||||
}
|
||||
else if (error != GIT_ENOTFOUND)
|
||||
if ((error = git_repository_config__weakptr(&config, repo)) < 0)
|
||||
return error;
|
||||
else {
|
||||
giterr_clear();
|
||||
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
else if (parent_path && git_path_isdir(parent_path->ptr))
|
||||
repo->workdir = git_buf_detach(parent_path);
|
||||
else {
|
||||
if (git_path_dirname_r(&worktree, repo->path_repository) < 0 ||
|
||||
git_path_to_dir(&worktree) < 0)
|
||||
return -1;
|
||||
|
||||
repo->workdir = git_buf_detach(&worktree);
|
||||
}
|
||||
|
||||
GITERR_CHECK_ALLOC(repo->workdir);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -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 (old && !overwrite)
|
||||
if (ce && !overwrite)
|
||||
goto cleanup;
|
||||
if ((!old && !value) || (old && value && strcmp(old, value) == 0))
|
||||
if (value && ce && ce->value && !strcmp(ce->value, value))
|
||||
goto cleanup;
|
||||
if (!value && (!ce || !ce->value))
|
||||
goto cleanup;
|
||||
|
||||
if (!value)
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user