int git_remote__get_http_proxy(git_remote *remote, bool use_ssl, char **proxy_url) { git_config *cfg; const git_config_entry *ce; const char *val = NULL; int error; assert(remote); if (!proxy_url || !remote->repo) return -1; *proxy_url = NULL; if ((error = git_repository_config__weakptr(&cfg, remote->repo)) < 0) return error; /* Go through the possible sources for proxy configuration, from most specific * to least specific. */ /* remote.<name>.proxy config setting */ 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; error = git_config__lookup_entry(&ce, cfg, git_buf_cstr(&buf), false); git_buf_free(&buf); if (error < 0) return error; if (ce && ce->value) { val = ce->value; goto found; } } /* http.proxy config setting */ if ((error = git_config__lookup_entry(&ce, cfg, "http.proxy", false)) < 0) return error; if (ce && ce->value) { val = ce->value; goto found; } /* HTTP_PROXY / HTTPS_PROXY environment variables */ val = use_ssl ? getenv("HTTPS_PROXY") : getenv("HTTP_PROXY"); found: if (val && val[0]) { *proxy_url = git__strdup(val); GITERR_CHECK_ALLOC(*proxy_url); } return 0; }
static int attr_cache__lookup_path( char **out, git_config *cfg, const char *key, const char *fallback) { git_buf buf = GIT_BUF_INIT; int error; git_config_entry *entry = NULL; *out = NULL; 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] == '/' && !git_sysdir_find_global_file(&buf, &cfgval[2])) *out = git_buf_detach(&buf); else if (cfgval) *out = git__strdup(cfgval); } else if (!git_sysdir_find_xdg_file(&buf, fallback)) *out = git_buf_detach(&buf); git_config_entry_free(entry); git_buf_free(&buf); return error; }
static int load_workdir(git_repository *repo, git_config *config, git_buf *parent_path) { int error; const git_config_entry *ce; git_buf worktree = GIT_BUF_INIT; if (repo->is_bare) return 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); } 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; }
int git_config__cvar(int *out, git_config *config, git_cvar_cached cvar) { int error = 0; struct map_data *data = &_cvar_maps[(int)cvar]; const git_config_entry *entry; git_config__lookup_entry(&entry, config, data->cvar_name, false); if (!entry) *out = data->default_value; 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); return error; }
static int download_tags_value(git_remote *remote, git_config *cfg) { const git_config_entry *ce; git_buf buf = GIT_BUF_INIT; int error; /* The 0 value is the default (auto), let's see if we need to change it */ if (git_buf_printf(&buf, "remote.%s.tagopt", remote->name) < 0) return -1; error = git_config__lookup_entry(&ce, cfg, git_buf_cstr(&buf), false); git_buf_free(&buf); 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; }
static int git_diff_driver_load( git_diff_driver **out, git_repository *repo, const char *driver_name) { int error = 0; git_diff_driver_registry *reg; git_diff_driver *drv = NULL; size_t namelen = strlen(driver_name); khiter_t pos; git_config *cfg; git_buf name = GIT_BUF_INIT; const git_config_entry *ce; bool found_driver = false; if ((reg = git_repository_driver_registry(repo)) == NULL) return -1; pos = git_strmap_lookup_index(reg->drivers, driver_name); if (git_strmap_valid_index(reg->drivers, pos)) { *out = git_strmap_value_at(reg->drivers, pos); return 0; } drv = git__calloc(1, sizeof(git_diff_driver) + namelen + 1); GITERR_CHECK_ALLOC(drv); drv->type = DIFF_DRIVER_AUTO; memcpy(drv->name, driver_name, namelen); /* if you can't read config for repo, just use default driver */ if (git_repository_config_snapshot(&cfg, repo) < 0) { giterr_clear(); goto done; } if ((error = git_buf_printf(&name, "diff.%s.binary", driver_name)) < 0) goto done; 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; 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 or "auto", so just continue */ break; } /* TODO: warn if diff.<name>.command or diff.<name>.textconv are set */ git_buf_truncate(&name, namelen + strlen("diff..")); git_buf_put(&name, "xfuncname", strlen("xfuncname")); if ((error = git_config_get_multivar_foreach( cfg, name.ptr, NULL, diff_driver_xfuncname, drv)) < 0) { if (error != GIT_ENOTFOUND) goto done; giterr_clear(); /* no diff.<driver>.xfuncname, so just continue */ } git_buf_truncate(&name, namelen + strlen("diff..")); git_buf_put(&name, "funcname", strlen("funcname")); if ((error = git_config_get_multivar_foreach( cfg, name.ptr, NULL, diff_driver_funcname, drv)) < 0) { if (error != GIT_ENOTFOUND) goto done; giterr_clear(); /* no diff.<driver>.funcname, so just continue */ } /* if we found any patterns, set driver type to use correct callback */ if (git_array_size(drv->fn_patterns) > 0) { drv->type = DIFF_DRIVER_PATTERNLIST; found_driver = true; } git_buf_truncate(&name, namelen + strlen("diff..")); git_buf_put(&name, "wordregex", strlen("wordregex")); 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; } /* TODO: look up diff.<driver>.algorithm to turn on minimal / patience * diff in drv->other_flags */ /* if no driver config found at all, fall back on AUTO driver */ if (!found_driver) goto done; /* store driver in registry */ git_strmap_insert(reg->drivers, drv->name, drv, error); if (error < 0) goto done; error = 0; *out = drv; done: git_buf_free(&name); git_config_free(cfg); if (!*out) { int error2 = git_diff_driver_builtin(out, reg, driver_name); if (!error) error = error2; } if (drv && drv != *out) git_diff_driver_free(drv); return error; }
int git_remote_save(const git_remote *remote) { int error; git_config *cfg; const char *tagopt = NULL; git_buf buf = GIT_BUF_INIT; const git_config_entry *existing; assert(remote); if (!remote->name) { giterr_set(GITERR_INVALID, "Can't save an anonymous remote."); return GIT_EINVALIDSPEC; } if ((error = ensure_remote_name_is_valid(remote->name)) < 0) return error; if ((error = git_repository_config__weakptr(&cfg, remote->repo)) < 0) return error; if ((error = git_buf_printf(&buf, "remote.%s.url", remote->name)) < 0) return error; /* after this point, buffer is allocated so end with cleanup */ if ((error = git_config_set_string( cfg, git_buf_cstr(&buf), remote->url)) < 0) goto cleanup; git_buf_clear(&buf); if ((error = git_buf_printf(&buf, "remote.%s.pushurl", remote->name)) < 0) goto cleanup; if ((error = git_config__update_entry( cfg, git_buf_cstr(&buf), remote->pushurl, true, false)) < 0) goto cleanup; if ((error = update_config_refspec(remote, cfg, GIT_DIRECTION_FETCH)) < 0) goto cleanup; if ((error = update_config_refspec(remote, cfg, GIT_DIRECTION_PUSH)) < 0) goto cleanup; /* * What action to take depends on the old and new values. This * is describes by the table below. tagopt means whether the * is already a value set in the config * * AUTO ALL or NONE * +-----------------------+ * tagopt | remove | set | * +---------+-------------| * !tagopt | nothing | set | * +---------+-------------+ */ git_buf_clear(&buf); if ((error = git_buf_printf(&buf, "remote.%s.tagopt", remote->name)) < 0) goto cleanup; if ((error = git_config__lookup_entry( &existing, cfg, git_buf_cstr(&buf), false)) < 0) goto cleanup; if (remote->download_tags == GIT_REMOTE_DOWNLOAD_TAGS_ALL) tagopt = "--tags"; else if (remote->download_tags == GIT_REMOTE_DOWNLOAD_TAGS_NONE) tagopt = "--no-tags"; else if (existing != NULL) tagopt = NULL; error = git_config__update_entry( cfg, git_buf_cstr(&buf), tagopt, true, false); cleanup: git_buf_free(&buf); return error; }