예제 #1
0
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;
}
예제 #2
0
파일: attrcache.c 프로젝트: 1336/libgit2
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;
}
예제 #3
0
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;
}
예제 #4
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;
}
예제 #5
0
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;
}
예제 #6
0
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;
}
예제 #7
0
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;
}