/* * Copyright (C) the libgit2 contributors. All rights reserved. * * This file is part of libgit2, distributed under the GNU GPL v2 with * a Linking Exception. For full terms see the included COPYING file. */ #ifndef INCLUDE_git_config_h__ #define INCLUDE_git_config_h__ #include "common.h" #include "types.h" /** * @file git2/config.h * @brief Git config management routines * @defgroup git_config Git config management routines * @ingroup Git * @{ */ GIT_BEGIN_DECL /** * Priority level of a config file. * These priority levels correspond to the natural escalation logic * (from higher to lower) when searching for config entries in git.git. * * git_config_open_default() and git_repository_config() honor those * priority levels as well. */ enum { GIT_CONFIG_LEVEL_SYSTEM = 1, /**< System-wide configuration file. */ GIT_CONFIG_LEVEL_XDG = 2, /**< XDG compatible configuration file (.config/git/config). */ GIT_CONFIG_LEVEL_GLOBAL = 3, /**< User-specific configuration file, also called Global configuration file. */ GIT_CONFIG_LEVEL_LOCAL = 4, /**< Repository specific configuration file. */ GIT_CONFIG_HIGHEST_LEVEL = -1, /**< Represents the highest level of a config file. */ }; typedef struct { const char *name; const char *value; unsigned int level; } git_config_entry; typedef int (*git_config_foreach_cb)(const git_config_entry *, void *); /** * Generic backend that implements the interface to * access a configuration file */ struct git_config_backend { unsigned int version; struct git_config *cfg; /* Open means open the file/database and parse if necessary */ int (*open)(struct git_config_backend *, unsigned int level); int (*get)(const struct git_config_backend *, const char *key, const git_config_entry **entry); int (*get_multivar)(struct git_config_backend *, const char *key, const char *regexp, git_config_foreach_cb callback, void *payload); int (*set)(struct git_config_backend *, const char *key, const char *value); int (*set_multivar)(git_config_backend *cfg, const char *name, const char *regexp, const char *value); int (*del)(struct git_config_backend *, const char *key); int (*foreach)(struct git_config_backend *, const char *, git_config_foreach_cb callback, void *payload); int (*refresh)(struct git_config_backend *); void (*free)(struct git_config_backend *); }; #define GIT_CONFIG_BACKEND_VERSION 1 #define GIT_CONFIG_BACKEND_INIT {GIT_CONFIG_BACKEND_VERSION} typedef enum { GIT_CVAR_FALSE = 0, GIT_CVAR_TRUE = 1, GIT_CVAR_INT32, GIT_CVAR_STRING } git_cvar_t; typedef struct { git_cvar_t cvar_type; const char *str_match; int map_value; } git_cvar_map; /** * Locate the path to the global configuration file * * The user or global configuration file is usually * located in `$HOME/.gitconfig`. * * This method will try to guess the full path to that * file, if the file exists. The returned path * may be used on any `git_config` call to load the * global configuration file. * * This method will not guess the path to the xdg compatible * config file (.config/git/config). * * @param out Buffer to store the path in * @param length size of the buffer in bytes * @return 0 if a global configuration file has been found. Its path will be stored in `buffer`. */ GIT_EXTERN(int) git_config_find_global(char *out, size_t length); /** * Locate the path to the global xdg compatible configuration file * * The xdg compatible configuration file is usually * located in `$HOME/.config/git/config`. * * This method will try to guess the full path to that * file, if the file exists. The returned path * may be used on any `git_config` call to load the * xdg compatible configuration file. * * @param out Buffer to store the path in * @param length size of the buffer in bytes * @return 0 if a xdg compatible configuration file has been * found. Its path will be stored in `buffer`. */ GIT_EXTERN(int) git_config_find_xdg(char *out, size_t length); /** * Locate the path to the system configuration file * * If /etc/gitconfig doesn't exist, it will look for * %PROGRAMFILES%\Git\etc\gitconfig. * @param global_config_path Buffer to store the path in * @param length size of the buffer in bytes * @return 0 if a system configuration file has been * found. Its path will be stored in `buffer`. */ GIT_EXTERN(int) git_config_find_system(char *out, size_t length); /** * Open the global, XDG and system configuration files * * Utility wrapper that finds the global, XDG and system configuration files * and opens them into a single prioritized config object that can be * used when accessing default config data outside a repository. * * @param out Pointer to store the config instance * @return 0 or an error code */ GIT_EXTERN(int) git_config_open_default(git_config **out); /** * Allocate a new configuration object * * This object is empty, so you have to add a file to it before you * can do anything with it. * * @param out pointer to the new configuration * @return 0 or an error code */ GIT_EXTERN(int) git_config_new(git_config **out); /** * Add a generic config file instance to an existing config * * Note that the configuration object will free the file * automatically. * * Further queries on this config object will access each * of the config file instances in order (instances with * a higher priority level will be accessed first). * * @param cfg the configuration to add the file to * @param file the configuration file (backend) to add * @param level the priority level of the backend * @param force if a config file already exists for the given * priority level, replace it * @return 0 on success, GIT_EEXISTS when adding more than one file * for a given priority level (and force_replace set to 0), or error code */ GIT_EXTERN(int) git_config_add_backend( git_config *cfg, git_config_backend *file, unsigned int level, int force); /** * Add an on-disk config file instance to an existing config * * The on-disk file pointed at by `path` will be opened and * parsed; it's expected to be a native Git config file following * the default Git config syntax (see man git-config). * * Note that the configuration object will free the file * automatically. * * Further queries on this config object will access each * of the config file instances in order (instances with * a higher priority level will be accessed first). * * @param cfg the configuration to add the file to * @param path path to the configuration file (backend) to add * @param level the priority level of the backend * @param force if a config file already exists for the given * priority level, replace it * @return 0 on success, GIT_EEXISTS when adding more than one file * for a given priority level (and force_replace set to 0), * GIT_ENOTFOUND when the file doesn't exist or error code */ GIT_EXTERN(int) git_config_add_file_ondisk( git_config *cfg, const char *path, unsigned int level, int force); /** * Create a new config instance containing a single on-disk file * * This method is a simple utility wrapper for the following sequence * of calls: * - git_config_new * - git_config_add_file_ondisk * * @param out The configuration instance to create * @param path Path to the on-disk file to open * @return 0 on success, GIT_ENOTFOUND when the file doesn't exist * or an error code */ GIT_EXTERN(int) git_config_open_ondisk(git_config **out, const char *path); /** * Build a single-level focused config object from a multi-level one. * * The returned config object can be used to perform get/set/delete operations * on a single specific level. * * Getting several times the same level from the same parent multi-level config * will return different config instances, but containing the same config_file * instance. * * @param out The configuration instance to create * @param parent Multi-level config to search for the given level * @param level Configuration level to search for * @return 0, GIT_ENOTFOUND if the passed level cannot be found in the * multi-level parent config, or an error code */ GIT_EXTERN(int) git_config_open_level( git_config **out, const git_config *parent, unsigned int level); /** * Reload changed config files * * A config file may be changed on disk out from under the in-memory * config object. This function causes us to look for files that have * been modified since we last loaded them and refresh the config with * the latest information. * * @param cfg The configuration to refresh * @return 0 or an error code */ GIT_EXTERN(int) git_config_refresh(git_config *cfg); /** * Free the configuration and its associated memory and files * * @param cfg the configuration to free */ GIT_EXTERN(void) git_config_free(git_config *cfg); /** * Get the git_config_entry of a config variable. * * The git_config_entry is owned by the config and should not be freed by the * user. * @param out pointer to the variable git_config_entry * @param cfg where to look for the variable * @param name the variable's name * @return 0 or an error code */ GIT_EXTERN(int) git_config_get_entry( const git_config_entry **out, const git_config *cfg, const char *name); /** * Get the value of an integer config variable. * * All config files will be looked into, in the order of their * defined level. A higher level means a higher priority. The * first occurence of the variable will be returned here. * * @param out pointer to the variable where the value should be stored * @param cfg where to look for the variable * @param name the variable's name * @return 0 or an error code */ GIT_EXTERN(int) git_config_get_int32(int32_t *out, const git_config *cfg, const char *name); /** * Get the value of a long integer config variable. * * All config files will be looked into, in the order of their * defined level. A higher level means a higher priority. The * first occurrence of the variable will be returned here. * * @param out pointer to the variable where the value should be stored * @param cfg where to look for the variable * @param name the variable's name * @return 0 or an error code */ GIT_EXTERN(int) git_config_get_int64(int64_t *out, const git_config *cfg, const char *name); /** * Get the value of a boolean config variable. * * This function uses the usual C convention of 0 being false and * anything else true. * * All config files will be looked into, in the order of their * defined level. A higher level means a higher priority. The * first occurrence of the variable will be returned here. * * @param out pointer to the variable where the value should be stored * @param cfg where to look for the variable * @param name the variable's name * @return 0 or an error code */ GIT_EXTERN(int) git_config_get_bool(int *out, const git_config *cfg, const char *name); /** * Get the value of a string config variable. * * The string is owned by the variable and should not be freed by the * user. * * All config files will be looked into, in the order of their * defined level. A higher level means a higher priority. The * first occurrence of the variable will be returned here. * * @param out pointer to the variable's value * @param cfg where to look for the variable * @param name the variable's name * @return 0 or an error code */ GIT_EXTERN(int) git_config_get_string(const char **out, const git_config *cfg, const char *name); /** * Get each value of a multivar. * * The callback will be called on each variable found * * @param cfg where to look for the variable * @param name the variable's name * @param regexp regular expression to filter which variables we're * interested in. Use NULL to indicate all * @param fn the function to be called on each value of the variable * @param data opaque pointer to pass to the callback */ GIT_EXTERN(int) git_config_get_multivar(const git_config *cfg, const char *name, const char *regexp, git_config_foreach_cb callback, void *payload); /** * Set the value of an integer config variable in the config file * with the highest level (usually the local one). * * @param cfg where to look for the variable * @param name the variable's name * @param value Integer value for the variable * @return 0 or an error code */ GIT_EXTERN(int) git_config_set_int32(git_config *cfg, const char *name, int32_t value); /** * Set the value of a long integer config variable in the config file * with the highest level (usually the local one). * * @param cfg where to look for the variable * @param name the variable's name * @param value Long integer value for the variable * @return 0 or an error code */ GIT_EXTERN(int) git_config_set_int64(git_config *cfg, const char *name, int64_t value); /** * Set the value of a boolean config variable in the config file * with the highest level (usually the local one). * * @param cfg where to look for the variable * @param name the variable's name * @param value the value to store * @return 0 or an error code */ GIT_EXTERN(int) git_config_set_bool(git_config *cfg, const char *name, int value); /** * Set the value of a string config variable in the config file * with the highest level (usually the local one). * * A copy of the string is made and the user is free to use it * afterwards. * * @param cfg where to look for the variable * @param name the variable's name * @param value the string to store. * @return 0 or an error code */ GIT_EXTERN(int) git_config_set_string(git_config *cfg, const char *name, const char *value); /** * Set a multivar in the local config file. * * @param cfg where to look for the variable * @param name the variable's name * @param regexp a regular expression to indicate which values to replace * @param value the new value. */ GIT_EXTERN(int) git_config_set_multivar(git_config *cfg, const char *name, const char *regexp, const char *value); /** * Delete a config variable from the config file * with the highest level (usually the local one). * * @param cfg the configuration * @param name the variable to delete */ GIT_EXTERN(int) git_config_delete_entry(git_config *cfg, const char *name); /** * Perform an operation on each config variable. * * The callback receives the normalized name and value of each variable * in the config backend, and the data pointer passed to this function. * As soon as one of the callback functions returns something other than 0, * this function stops iterating and returns `GIT_EUSER`. * * @param cfg where to get the variables from * @param callback the function to call on each variable * @param payload the data to pass to the callback * @return 0 on success, GIT_EUSER on non-zero callback, or error code */ GIT_EXTERN(int) git_config_foreach( const git_config *cfg, git_config_foreach_cb callback, void *payload); /** * Perform an operation on each config variable matching a regular expression. * * This behaviors like `git_config_foreach` with an additional filter of a * regular expression that filters which config keys are passed to the * callback. * * @param cfg where to get the variables from * @param regexp regular expression to match against config names * @param callback the function to call on each variable * @param payload the data to pass to the callback * @return 0 or the return value of the callback which didn't return 0 */ GIT_EXTERN(int) git_config_foreach_match( const git_config *cfg, const char *regexp, git_config_foreach_cb callback, void *payload); /** * Query the value of a config variable and return it mapped to * an integer constant. * * This is a helper method to easily map different possible values * to a variable to integer constants that easily identify them. * * A mapping array looks as follows: * * git_cvar_map autocrlf_mapping[] = { * {GIT_CVAR_FALSE, NULL, GIT_AUTO_CRLF_FALSE}, * {GIT_CVAR_TRUE, NULL, GIT_AUTO_CRLF_TRUE}, * {GIT_CVAR_STRING, "input", GIT_AUTO_CRLF_INPUT}, * {GIT_CVAR_STRING, "default", GIT_AUTO_CRLF_DEFAULT}}; * * On any "false" value for the variable (e.g. "false", "FALSE", "no"), the * mapping will store `GIT_AUTO_CRLF_FALSE` in the `out` parameter. * * The same thing applies for any "true" value such as "true", "yes" or "1", storing * the `GIT_AUTO_CRLF_TRUE` variable. * * Otherwise, if the value matches the string "input" (with case insensitive comparison), * the given constant will be stored in `out`, and likewise for "default". * * If not a single match can be made to store in `out`, an error code will be * returned. * * @param out place to store the result of the mapping * @param cfg config file to get the variables from * @param name name of the config variable to lookup * @param maps array of `git_cvar_map` objects specifying the possible mappings * @param map_n number of mapping objects in `maps` * @return 0 on success, error code otherwise */ GIT_EXTERN(int) git_config_get_mapped( int *out, const git_config *cfg, const char *name, const git_cvar_map *maps, size_t map_n); /** * Maps a string value to an integer constant * * @param out place to store the result of the parsing * @param maps array of `git_cvar_map` objects specifying the possible mappings * @param map_n number of mapping objects in `maps` * @param value value to parse */ GIT_EXTERN(int) git_config_lookup_map_value( int *out, const git_cvar_map *maps, size_t map_n, const char *value); /** * Parse a string value as a bool. * * Valid values for true are: 'true', 'yes', 'on', 1 or any * number different from 0 * Valid values for false are: 'false', 'no', 'off', 0 * * @param out place to store the result of the parsing * @param value value to parse */ GIT_EXTERN(int) git_config_parse_bool(int *out, const char *value); /** * Parse a string value as an int32. * * An optional value suffix of 'k', 'm', or 'g' will * cause the value to be multiplied by 1024, 1048576, * or 1073741824 prior to output. * * @param out place to store the result of the parsing * @param value value to parse */ GIT_EXTERN(int) git_config_parse_int32(int32_t *out, const char *value); /** * Parse a string value as an int64. * * An optional value suffix of 'k', 'm', or 'g' will * cause the value to be multiplied by 1024, 1048576, * or 1073741824 prior to output. * * @param out place to store the result of the parsing * @param value value to parse */ GIT_EXTERN(int) git_config_parse_int64(int64_t *out, const char *value); /** @} */ GIT_END_DECL #endif