git/config.c

/*
 * GIT - The information manager from hell
 *
 * Copyright (C) Linus Torvalds, 2005
 * Copyright (C) Johannes Schindelin, 2005
 *
 */

#define USE_THE_REPOSITORY_VARIABLE

#include "git-compat-util.h"
#include "abspath.h"
#include "advice.h"
#include "date.h"
#include "branch.h"
#include "config.h"
#include "parse.h"
#include "convert.h"
#include "environment.h"
#include "gettext.h"
#include "ident.h"
#include "repository.h"
#include "lockfile.h"
#include "mailmap.h"
#include "attr.h"
#include "exec-cmd.h"
#include "strbuf.h"
#include "quote.h"
#include "hashmap.h"
#include "string-list.h"
#include "object-name.h"
#include "object-store-ll.h"
#include "pager.h"
#include "path.h"
#include "utf8.h"
#include "color.h"
#include "refs.h"
#include "setup.h"
#include "strvec.h"
#include "trace2.h"
#include "wildmatch.h"
#include "ws.h"
#include "write-or-die.h"

struct config_source {};
#define CONFIG_SOURCE_INIT

static int pack_compression_seen;
static int zlib_compression_seen;

/*
 * Config that comes from trusted scopes, namely:
 * - CONFIG_SCOPE_SYSTEM (e.g. /etc/gitconfig)
 * - CONFIG_SCOPE_GLOBAL (e.g. $HOME/.gitconfig, $XDG_CONFIG_HOME/git)
 * - CONFIG_SCOPE_COMMAND (e.g. "-c" option, environment variables)
 *
 * This is declared here for code cleanliness, but unlike the other
 * static variables, this does not hold config parser state.
 */
static struct config_set protected_config;

static int config_file_fgetc(struct config_source *conf)
{}

static int config_file_ungetc(int c, struct config_source *conf)
{}

static long config_file_ftell(struct config_source *conf)
{}

static int config_buf_fgetc(struct config_source *conf)
{}

static int config_buf_ungetc(int c, struct config_source *conf)
{}

static long config_buf_ftell(struct config_source *conf)
{}

struct config_include_data {};
#define CONFIG_INCLUDE_INIT

static int git_config_include(const char *var, const char *value,
			      const struct config_context *ctx, void *data);

#define MAX_INCLUDE_DEPTH
static const char include_depth_advice[] =);
static int handle_path_include(const struct key_value_info *kvi,
			       const char *path,
			       struct config_include_data *inc)
{}

static void add_trailing_starstar_for_dir(struct strbuf *pat)
{}

static int prepare_include_condition_pattern(const struct key_value_info *kvi,
					     struct strbuf *pat)
{}

static int include_by_gitdir(const struct key_value_info *kvi,
			     const struct config_options *opts,
			     const char *cond, size_t cond_len, int icase)
{}

static int include_by_branch(struct config_include_data *data,
			     const char *cond, size_t cond_len)
{}

static int add_remote_url(const char *var, const char *value,
			  const struct config_context *ctx UNUSED, void *data)
{}

static void populate_remote_urls(struct config_include_data *inc)
{}

static int forbid_remote_url(const char *var, const char *value UNUSED,
			     const struct config_context *ctx UNUSED,
			     void *data UNUSED)
{}

static int at_least_one_url_matches_glob(const char *glob, int glob_len,
					 struct string_list *remote_urls)
{}

static int include_by_remote_url(struct config_include_data *inc,
		const char *cond, size_t cond_len)
{}

static int include_condition_is_true(const struct key_value_info *kvi,
				     struct config_include_data *inc,
				     const char *cond, size_t cond_len)
{}

static int git_config_include(const char *var, const char *value,
			      const struct config_context *ctx,
			      void *data)
{}

static void git_config_push_split_parameter(const char *key, const char *value)
{}

void git_config_push_parameter(const char *text)
{}

void git_config_push_env(const char *spec)
{}

static inline int iskeychar(int c)
{}

/*
 * Auxiliary function to sanity-check and split the key into the section
 * identifier and variable name.
 *
 * Returns 0 on success, -1 when there is an invalid character in the key and
 * -2 if there is no section name in the key.
 *
 * store_key - pointer to char* which will hold a copy of the key with
 *             lowercase section and variable name
 * baselen - pointer to size_t which will hold the length of the
 *           section + subsection part, can be NULL
 */
int git_config_parse_key(const char *key, char **store_key, size_t *baselen_)
{}

static int config_parse_pair(const char *key, const char *value,
			     struct key_value_info *kvi,
			     config_fn_t fn, void *data)
{}


/* for values read from `git_config_from_parameters()` */
void kvi_from_param(struct key_value_info *out)
{}

int git_config_parse_parameter(const char *text,
			       config_fn_t fn, void *data)
{}

static int parse_config_env_list(char *env, struct key_value_info *kvi,
				 config_fn_t fn, void *data)
{}

int git_config_from_parameters(config_fn_t fn, void *data)
{}

static int get_next_char(struct config_source *cs)
{}

static char *parse_value(struct config_source *cs)
{}

static int get_value(struct config_source *cs, struct key_value_info *kvi,
		     config_fn_t fn, void *data, struct strbuf *name)
{}

static int get_extended_base_var(struct config_source *cs, struct strbuf *name,
				 int c)
{}

static int get_base_var(struct config_source *cs, struct strbuf *name)
{}

struct parse_event_data {};

static int do_event(struct config_source *cs, enum config_event_t type,
		    struct parse_event_data *data)
{}

static void kvi_from_source(struct config_source *cs,
			    enum config_scope scope,
			    struct key_value_info *out)
{}

static int git_parse_source(struct config_source *cs, config_fn_t fn,
			    struct key_value_info *kvi, void *data,
			    const struct config_options *opts)
{}

NORETURN
static void die_bad_number(const char *name, const char *value,
			   const struct key_value_info *kvi)
{}

int git_config_int(const char *name, const char *value,
		   const struct key_value_info *kvi)
{}

int64_t git_config_int64(const char *name, const char *value,
			 const struct key_value_info *kvi)
{}

unsigned long git_config_ulong(const char *name, const char *value,
			       const struct key_value_info *kvi)
{}

ssize_t git_config_ssize_t(const char *name, const char *value,
			   const struct key_value_info *kvi)
{}

double git_config_double(const char *name, const char *value,
			 const struct key_value_info *kvi)
{}

static const struct fsync_component_name {} fsync_component_names[] =;

static enum fsync_component parse_fsync_components(const char *var, const char *string)
{}

int git_config_bool_or_int(const char *name, const char *value,
			   const struct key_value_info *kvi, int *is_bool)
{}

int git_config_bool(const char *name, const char *value)
{}

int git_config_string(char **dest, const char *var, const char *value)
{}

int git_config_pathname(char **dest, const char *var, const char *value)
{}

int git_config_expiry_date(timestamp_t *timestamp, const char *var, const char *value)
{}

int git_config_color(char *dest, const char *var, const char *value)
{}

static int git_default_core_config(const char *var, const char *value,
				   const struct config_context *ctx, void *cb)
{}

static int git_default_sparse_config(const char *var, const char *value)
{}

static int git_default_i18n_config(const char *var, const char *value)
{}

static int git_default_branch_config(const char *var, const char *value)
{}

static int git_default_push_config(const char *var, const char *value)
{}

static int git_default_mailmap_config(const char *var, const char *value)
{}

static int git_default_attr_config(const char *var, const char *value)
{}

int git_default_config(const char *var, const char *value,
		       const struct config_context *ctx, void *cb)
{}

/*
 * All source specific fields in the union, die_on_error, name and the callbacks
 * fgetc, ungetc, ftell of top need to be initialized before calling
 * this function.
 */
static int do_config_from(struct config_source *top, config_fn_t fn,
			  void *data, enum config_scope scope,
			  const struct config_options *opts)
{}

static int do_config_from_file(config_fn_t fn,
			       const enum config_origin_type origin_type,
			       const char *name, const char *path, FILE *f,
			       void *data, enum config_scope scope,
			       const struct config_options *opts)
{}

static int git_config_from_stdin(config_fn_t fn, void *data,
				 enum config_scope scope)
{}

int git_config_from_file_with_options(config_fn_t fn, const char *filename,
				      void *data, enum config_scope scope,
				      const struct config_options *opts)
{}

int git_config_from_file(config_fn_t fn, const char *filename, void *data)
{}

int git_config_from_mem(config_fn_t fn,
			const enum config_origin_type origin_type,
			const char *name, const char *buf, size_t len,
			void *data, enum config_scope scope,
			const struct config_options *opts)
{}

int git_config_from_blob_oid(config_fn_t fn,
			      const char *name,
			      struct repository *repo,
			      const struct object_id *oid,
			      void *data,
			      enum config_scope scope)
{}

static int git_config_from_blob_ref(config_fn_t fn,
				    struct repository *repo,
				    const char *name,
				    void *data,
				    enum config_scope scope)
{}

char *git_system_config(void)
{}

char *git_global_config(void)
{}

void git_global_config_paths(char **user_out, char **xdg_out)
{}

int git_config_system(void)
{}

static int do_git_config_sequence(const struct config_options *opts,
				  const struct repository *repo,
				  config_fn_t fn, void *data)
{}

int config_with_options(config_fn_t fn, void *data,
			const struct git_config_source *config_source,
			struct repository *repo,
			const struct config_options *opts)
{}

static void configset_iter(struct config_set *set, config_fn_t fn, void *data)
{}

void read_early_config(struct repository *repo, config_fn_t cb, void *data)
{}

void read_very_early_config(config_fn_t cb, void *data)
{}

RESULT_MUST_BE_USED
static int configset_find_element(struct config_set *set, const char *key,
				  struct config_set_element **dest)
{}

static int configset_add_value(const struct key_value_info *kvi_p,
			       struct config_set *set, const char *key,
			       const char *value)
{}

static int config_set_element_cmp(const void *cmp_data UNUSED,
				  const struct hashmap_entry *eptr,
				  const struct hashmap_entry *entry_or_key,
				  const void *keydata UNUSED)
{}

void git_configset_init(struct config_set *set)
{}

void git_configset_clear(struct config_set *set)
{}

static int config_set_callback(const char *key, const char *value,
			       const struct config_context *ctx,
			       void *cb)
{}

int git_configset_add_file(struct config_set *set, const char *filename)
{}

int git_configset_get_value(struct config_set *set, const char *key,
			    const char **value, struct key_value_info *kvi)
{}

int git_configset_get_value_multi(struct config_set *set, const char *key,
				  const struct string_list **dest)
{}

static int check_multi_string(struct string_list_item *item, void *util)
{}

int git_configset_get_string_multi(struct config_set *cs, const char *key,
				   const struct string_list **dest)
{}

int git_configset_get(struct config_set *set, const char *key)
{}

int git_configset_get_string(struct config_set *set, const char *key, char **dest)
{}

static int git_configset_get_string_tmp(struct config_set *set, const char *key,
					const char **dest)
{}

int git_configset_get_int(struct config_set *set, const char *key, int *dest)
{}

int git_configset_get_ulong(struct config_set *set, const char *key, unsigned long *dest)
{}

int git_configset_get_bool(struct config_set *set, const char *key, int *dest)
{}

int git_configset_get_bool_or_int(struct config_set *set, const char *key,
				int *is_bool, int *dest)
{}

int git_configset_get_maybe_bool(struct config_set *set, const char *key, int *dest)
{}

int git_configset_get_pathname(struct config_set *set, const char *key, char **dest)
{}

/* Functions use to read configuration from a repository */
static void repo_read_config(struct repository *repo)
{}

static void git_config_check_init(struct repository *repo)
{}

void repo_config_clear(struct repository *repo)
{}

void repo_config(struct repository *repo, config_fn_t fn, void *data)
{}

int repo_config_get(struct repository *repo, const char *key)
{}

int repo_config_get_value(struct repository *repo,
			  const char *key, const char **value)
{}

int repo_config_get_value_multi(struct repository *repo, const char *key,
				const struct string_list **dest)
{}

int repo_config_get_string_multi(struct repository *repo, const char *key,
				 const struct string_list **dest)
{}

int repo_config_get_string(struct repository *repo,
			   const char *key, char **dest)
{}

int repo_config_get_string_tmp(struct repository *repo,
			       const char *key, const char **dest)
{}

int repo_config_get_int(struct repository *repo,
			const char *key, int *dest)
{}

int repo_config_get_ulong(struct repository *repo,
			  const char *key, unsigned long *dest)
{}

int repo_config_get_bool(struct repository *repo,
			 const char *key, int *dest)
{}

int repo_config_get_bool_or_int(struct repository *repo,
				const char *key, int *is_bool, int *dest)
{}

int repo_config_get_maybe_bool(struct repository *repo,
			       const char *key, int *dest)
{}

int repo_config_get_pathname(struct repository *repo,
			     const char *key, char **dest)
{}

/* Read values into protected_config. */
static void read_protected_config(void)
{}

void git_protected_config(config_fn_t fn, void *data)
{}

int repo_config_get_expiry(struct repository *r, const char *key, char **output)
{}

int repo_config_get_expiry_in_days(struct repository *r, const char *key,
				   timestamp_t *expiry, timestamp_t now)
{}

int repo_config_get_split_index(struct repository *r)
{}

int repo_config_get_max_percent_split_change(struct repository *r)
{}

int repo_config_get_index_threads(struct repository *r, int *dest)
{}

NORETURN
void git_die_config_linenr(const char *key, const char *filename, int linenr)
{}

void git_die_config(struct repository *r, const char *key, const char *err, ...)
{}

/*
 * Find all the stuff for git_config_set() below.
 */

struct config_store_data {};
#define CONFIG_STORE_INIT

static void config_store_data_clear(struct config_store_data *store)
{}

static int matches(const char *key, const char *value,
		   const struct config_store_data *store)
{}

static int store_aux_event(enum config_event_t type, size_t begin, size_t end,
			   struct config_source *cs, void *data)
{}

static int store_aux(const char *key, const char *value,
		     const struct config_context *ctx UNUSED, void *cb)
{}

static int write_error(const char *filename)
{}

static struct strbuf store_create_section(const char *key,
					  const struct config_store_data *store)
{}

static ssize_t write_section(int fd, const char *key,
			     const struct config_store_data *store)
{}

static ssize_t write_pair(int fd, const char *key, const char *value,
			  const char *comment,
			  const struct config_store_data *store)
{}

/*
 * If we are about to unset the last key(s) in a section, and if there are
 * no comments surrounding (or included in) the section, we will want to
 * extend begin/end to remove the entire section.
 *
 * Note: the parameter `seen_ptr` points to the index into the store.seen
 * array.  * This index may be incremented if a section has more than one
 * entry (which all are to be removed).
 */
static void maybe_remove_section(struct config_store_data *store,
				 size_t *begin_offset, size_t *end_offset,
				 int *seen_ptr)
{}

int repo_config_set_in_file_gently(struct repository *r, const char *config_filename,
				   const char *key, const char *comment, const char *value)
{}

void repo_config_set_in_file(struct repository *r, const char *config_filename,
			     const char *key, const char *value)
{}

int repo_config_set_gently(struct repository *r, const char *key, const char *value)
{}

int repo_config_set_worktree_gently(struct repository *r,
				    const char *key, const char *value)
{}

void repo_config_set(struct repository *r, const char *key, const char *value)
{}

char *git_config_prepare_comment_string(const char *comment)
{}

static void validate_comment_string(const char *comment)
{}

/*
 * If value==NULL, unset in (remove from) config,
 * if value_pattern!=NULL, disregard key/value pairs where value does not match.
 * if value_pattern==CONFIG_REGEX_NONE, do not match any existing values
 *     (only add a new one)
 * if flags contains the CONFIG_FLAGS_MULTI_REPLACE flag, all matching
 *     key/values are removed before a single new pair is written. If the
 *     flag is not present, then replace only the first match.
 *
 * Returns 0 on success.
 *
 * This function does this:
 *
 * - it locks the config file by creating ".git/config.lock"
 *
 * - it then parses the config using store_aux() as validator to find
 *   the position on the key/value pair to replace. If it is to be unset,
 *   it must be found exactly once.
 *
 * - the config file is mmap()ed and the part before the match (if any) is
 *   written to the lock file, then the changed part and the rest.
 *
 * - the config file is removed and the lock file rename()d to it.
 *
 */
int repo_config_set_multivar_in_file_gently(struct repository *r,
					    const char *config_filename,
					    const char *key, const char *value,
					    const char *value_pattern,
					    const char *comment,
					    unsigned flags)
{}

void repo_config_set_multivar_in_file(struct repository *r,
				      const char *config_filename,
				      const char *key, const char *value,
				      const char *value_pattern, unsigned flags)
{}

int repo_config_set_multivar_gently(struct repository *r, const char *key,
				    const char *value,
				    const char *value_pattern, unsigned flags)
{}

void repo_config_set_multivar(struct repository *r,
			      const char *key, const char *value,
			      const char *value_pattern, unsigned flags)
{}

static size_t section_name_match (const char *buf, const char *name)
{}

static int section_name_is_ok(const char *name)
{}

#define GIT_CONFIG_MAX_LINE_LEN

/* if new_name == NULL, the section is removed instead */
static int repo_config_copy_or_rename_section_in_file(
	struct repository *r,
	const char *config_filename,
	const char *old_name,
	const char *new_name, int copy)
{}

int repo_config_rename_section_in_file(struct repository *r, const char *config_filename,
				       const char *old_name, const char *new_name)
{}

int repo_config_rename_section(struct repository *r, const char *old_name, const char *new_name)
{}

int repo_config_copy_section_in_file(struct repository *r, const char *config_filename,
				     const char *old_name, const char *new_name)
{}

int repo_config_copy_section(struct repository *r, const char *old_name, const char *new_name)
{}

/*
 * Call this to report error for your variable that should not
 * get a boolean value (i.e. "[my] var" means "true").
 */
#undef config_error_nonbool
int config_error_nonbool(const char *var)
{}

int parse_config_key(const char *var,
		     const char *section,
		     const char **subsection, size_t *subsection_len,
		     const char **key)
{}

const char *config_origin_type_name(enum config_origin_type type)
{}

const char *config_scope_name(enum config_scope scope)
{}

int lookup_config(const char **mapping, int nr_mapping, const char *var)
{}